1个文件已删除
2个文件已修改
4 文件已复制
67个文件已添加
5 文件已重命名
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 694411f45e4e64facb88eebfc2e1df1c |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | userData: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 644a9f5710e62403c94066ef9b61e775 |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: bfc88fa65a0e6f44e88320a576c290a4 |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 9602a2783afdd234e9eabac2bdffbf7a |
| | | PluginImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | iconMap: {} |
| | | executionOrder: {} |
| | | defineConstraints: [] |
| | | isPreloaded: 0 |
| | | isOverridable: 0 |
| | | isExplicitlyReferenced: 0 |
| | | validateReferences: 1 |
| | | platformData: |
| | | - first: |
| | | : Any |
| | | second: |
| | | enabled: 0 |
| | | settings: |
| | | Exclude Android: 0 |
| | | Exclude Editor: 1 |
| | | Exclude Linux64: 1 |
| | | Exclude OSXUniversal: 1 |
| | | Exclude Win: 1 |
| | | Exclude Win64: 1 |
| | | - first: |
| | | Android: Android |
| | | second: |
| | | enabled: 1 |
| | | settings: |
| | | CPU: ARM64 |
| | | - first: |
| | | Any: |
| | | second: |
| | | enabled: 0 |
| | | settings: {} |
| | | - first: |
| | | Editor: Editor |
| | | second: |
| | | enabled: 0 |
| | | settings: |
| | | CPU: AnyCPU |
| | | DefaultValueInitialized: true |
| | | OS: AnyOS |
| | | - first: |
| | | Standalone: Linux64 |
| | | second: |
| | | enabled: 0 |
| | | settings: |
| | | CPU: None |
| | | - first: |
| | | Standalone: OSXUniversal |
| | | second: |
| | | enabled: 0 |
| | | settings: |
| | | CPU: None |
| | | - first: |
| | | Standalone: Win |
| | | second: |
| | | enabled: 0 |
| | | settings: |
| | | CPU: None |
| | | - first: |
| | | Standalone: Win64 |
| | | second: |
| | | enabled: 0 |
| | | settings: |
| | | CPU: None |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: fb7b442d8e32443e5856838741007f70 |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
File was renamed from Assets/Plugins/Android/libs/armeabi-v7a/libBugly.so.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: c9cdbdcbc4b089a4790f80e22bad555a |
| | | guid: 432060a129574479db0cfd441cdf3d69 |
| | | PluginImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
copy from Assets/Plugins/Android/libs/armeabi/libBugly.so.meta
copy to Assets/Plugins/BuglyPlugins/Android/libs/bugly.jar.meta
File was copied from Assets/Plugins/Android/libs/armeabi/libBugly.so.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: e9bd64f821527644883c202cd4c43abc |
| | | guid: 70c2f5016d12841a58b22885903c1170 |
| | | PluginImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | |
| | | - first: |
| | | Android: Android |
| | | second: |
| | | enabled: 0 |
| | | enabled: 1 |
| | | settings: {} |
| | | - first: |
| | | Any: |
File was renamed from Assets/Plugins/Android/libs/armeabi/libBugly.so.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: e9bd64f821527644883c202cd4c43abc |
| | | guid: 1db231dca0f72420cb880590f799d7d5 |
| | | PluginImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | |
| | | - first: |
| | | Android: Android |
| | | second: |
| | | enabled: 0 |
| | | enabled: 1 |
| | | settings: {} |
| | | - first: |
| | | Any: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 79531ba82725e4071861c982307805c3 |
| | | folderAsset: yes |
| | | timeCreated: 1443426231 |
| | | licenseType: Pro |
| | | DefaultImporter: |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
File was renamed from Assets/Plugins/Android/libs/x86/libBugly.so.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: b5f37d2635522b64a858008c47d3bcdc |
| | | guid: 16eaf0ec67588418783d6f5311aa71ce |
| | | PluginImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | |
| | | try { |
| | | // hold only one instance |
| | | |
| | | #if UNITY_5_3_OR_NEWER |
| | | #if UNITY_5 |
| | | Application.logMessageReceived += _OnLogCallbackHandler; |
| | | #else |
| | | Application.RegisterLogCallback (_OnLogCallbackHandler); |
| | |
| | | private static void _UnregisterExceptionHandler () |
| | | { |
| | | try { |
| | | #if UNITY_5_3_OR_NEWER |
| | | #if UNITY_5 |
| | | Application.logMessageReceived -= _OnLogCallbackHandler; |
| | | #else |
| | | Application.RegisterLogCallback (null); |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: bb0cfd908dccc6c4082e1f3d0b47cb78 |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
copy from Assets/Plugins/Android/libs/armeabi-v7a/libBugly.so.meta
copy to Assets/Plugins/BuglyPlugins/iOS/Bugly.framework.meta
File was copied from Assets/Plugins/Android/libs/armeabi-v7a/libBugly.so.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: c9cdbdcbc4b089a4790f80e22bad555a |
| | | guid: 2bda85a6801e046429399ec5e882b549 |
| | | folderAsset: yes |
| | | PluginImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | |
| | | validateReferences: 1 |
| | | platformData: |
| | | - first: |
| | | Android: Android |
| | | second: |
| | | enabled: 1 |
| | | settings: |
| | | CPU: ARMv7 |
| | | - first: |
| | | Any: |
| | | second: |
| | | enabled: 0 |
| | | enabled: 1 |
| | | settings: {} |
| | | - first: |
| | | Editor: Editor |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 8a2abdc417e6d3e4fafd2880d3d6ba03 |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: e411965cb1c2462439767aa31b7a25d9 |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | // |
| | | // Bugly.h |
| | | // Bugly |
| | | // |
| | | // Version: 2.4(8) |
| | | // |
| | | // Copyright (c) 2016年 Bugly. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | #import "BuglyConfig.h" |
| | | #import "BuglyLog.h" |
| | | |
| | | BLY_START_NONNULL |
| | | |
| | | @interface Bugly : NSObject |
| | | |
| | | /** |
| | | * 初始化Bugly,使用默认BuglyConfig |
| | | * |
| | | * @param appId 注册Bugly分配的应用唯一标识 |
| | | */ |
| | | + (void)startWithAppId:(NSString * BLY_NULLABLE)appId; |
| | | |
| | | /** |
| | | * 使用指定配置初始化Bugly |
| | | * |
| | | * @param appId 注册Bugly分配的应用唯一标识 |
| | | * @param config 传入配置的 BuglyConfig |
| | | */ |
| | | + (void)startWithAppId:(NSString * BLY_NULLABLE)appId |
| | | config:(BuglyConfig * BLY_NULLABLE)config; |
| | | |
| | | /** |
| | | * 使用指定配置初始化Bugly |
| | | * |
| | | * @param appId 注册Bugly分配的应用唯一标识 |
| | | * @param development 是否开发设备 |
| | | * @param config 传入配置的 BuglyConfig |
| | | */ |
| | | + (void)startWithAppId:(NSString * BLY_NULLABLE)appId |
| | | developmentDevice:(BOOL)development |
| | | config:(BuglyConfig * BLY_NULLABLE)config; |
| | | |
| | | /** |
| | | * 设置用户标识 |
| | | * |
| | | * @param userId 用户标识 |
| | | */ |
| | | + (void)setUserIdentifier:(NSString *)userId; |
| | | |
| | | /** |
| | | * 更新版本信息 |
| | | * |
| | | * @param version 应用版本信息 |
| | | */ |
| | | + (void)updateAppVersion:(NSString *)version; |
| | | |
| | | /** |
| | | * 设置关键数据,随崩溃信息上报 |
| | | * |
| | | * @param value KEY |
| | | * @param key VALUE |
| | | */ |
| | | + (void)setUserValue:(NSString *)value |
| | | forKey:(NSString *)key; |
| | | |
| | | /** |
| | | * 获取关键数据 |
| | | * |
| | | * @return 关键数据 |
| | | */ |
| | | + (NSDictionary * BLY_NULLABLE)allUserValues; |
| | | |
| | | /** |
| | | * 设置标签 |
| | | * |
| | | * @param tag 标签ID,可在网站生成 |
| | | */ |
| | | + (void)setTag:(NSUInteger)tag; |
| | | |
| | | /** |
| | | * 获取当前设置标签 |
| | | * |
| | | * @return 当前标签ID |
| | | */ |
| | | + (NSUInteger)currentTag; |
| | | |
| | | /** |
| | | * 获取设备ID |
| | | * |
| | | * @return 设备ID |
| | | */ |
| | | + (NSString *)buglyDeviceId; |
| | | |
| | | /** |
| | | * 上报自定义Objective-C异常 |
| | | * |
| | | * @param exception 异常信息 |
| | | */ |
| | | + (void)reportException:(NSException *)exception; |
| | | |
| | | /** |
| | | * 上报错误 |
| | | * |
| | | * @param error 错误信息 |
| | | */ |
| | | + (void)reportError:(NSError *)error; |
| | | |
| | | /** |
| | | * @brief 上报自定义错误 |
| | | * |
| | | * @param category 类型(Cocoa=3,CSharp=4,JS=5,Lua=6) |
| | | * @param aName 名称 |
| | | * @param aReason 错误原因 |
| | | * @param aStackArray 堆栈 |
| | | * @param info 附加数据 |
| | | * @param terminate 上报后是否退出应用进程 |
| | | */ |
| | | + (void)reportExceptionWithCategory:(NSUInteger)category name:(NSString *)aName reason:(NSString *)aReason callStack:(NSArray *)aStackArray extraInfo:(NSDictionary *)info terminateApp:(BOOL)terminate; |
| | | |
| | | /** |
| | | * SDK 版本信息 |
| | | * |
| | | * @return SDK版本号 |
| | | */ |
| | | + (NSString *)sdkVersion; |
| | | |
| | | /** |
| | | * App 是否发生了连续闪退 |
| | | * 如果启动SDK 且 5秒内 闪退,且次数达到 3次 则判定为连续闪退 |
| | | * |
| | | * @return 是否连续闪退 |
| | | */ |
| | | + (BOOL)isAppCrashedOnStartUpExceedTheLimit; |
| | | |
| | | + (void)setComponentIdentifier:(NSString *)componentId version:(NSString *)version; |
| | | |
| | | BLY_END_NONNULL |
| | | |
| | | @end |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 3bd9cef9c0bf2444caaff815e8b4856f |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | // |
| | | // BuglyConfig.h |
| | | // |
| | | // |
| | | // Copyright (c) 2016年 Tencent. All rights reserved. |
| | | // |
| | | |
| | | #pragma once |
| | | |
| | | #define BLY_UNAVAILABLE(x) __attribute__((unavailable(x))) |
| | | |
| | | #if __has_feature(nullability) |
| | | #define BLY_NONNULL __nonnull |
| | | #define BLY_NULLABLE __nullable |
| | | #define BLY_START_NONNULL _Pragma("clang assume_nonnull begin") |
| | | #define BLY_END_NONNULL _Pragma("clang assume_nonnull end") |
| | | #else |
| | | #define BLY_NONNULL |
| | | #define BLY_NULLABLE |
| | | #define BLY_START_NONNULL |
| | | #define BLY_END_NONNULL |
| | | #endif |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import "BuglyLog.h" |
| | | |
| | | BLY_START_NONNULL |
| | | |
| | | @protocol BuglyDelegate <NSObject> |
| | | |
| | | @optional |
| | | /** |
| | | * 发生异常时回调 |
| | | * |
| | | * @param exception 异常信息 |
| | | * |
| | | * @return 返回需上报记录,随异常上报一起上报 |
| | | */ |
| | | - (NSString * BLY_NULLABLE)attachmentForException:(NSException * BLY_NULLABLE)exception; |
| | | |
| | | @end |
| | | |
| | | @interface BuglyConfig : NSObject |
| | | |
| | | /** |
| | | * SDK Debug信息开关, 默认关闭 |
| | | */ |
| | | @property (nonatomic, assign) BOOL debugMode; |
| | | |
| | | /** |
| | | * 设置自定义渠道标识 |
| | | */ |
| | | @property (nonatomic, copy) NSString *channel; |
| | | |
| | | /** |
| | | * 设置自定义版本号 |
| | | */ |
| | | @property (nonatomic, copy) NSString *version; |
| | | |
| | | /** |
| | | * 设置自定义设备唯一标识 |
| | | */ |
| | | @property (nonatomic, copy) NSString *deviceIdentifier; |
| | | |
| | | /** |
| | | * 卡顿监控开关,默认关闭 |
| | | */ |
| | | @property (nonatomic) BOOL blockMonitorEnable; |
| | | |
| | | /** |
| | | * 卡顿监控判断间隔,单位为秒 |
| | | */ |
| | | @property (nonatomic) NSTimeInterval blockMonitorTimeout; |
| | | |
| | | /** |
| | | * 设置 App Groups Id (如有使用 Bugly iOS Extension SDK,请设置该值) |
| | | */ |
| | | @property (nonatomic, copy) NSString *applicationGroupIdentifier; |
| | | |
| | | /** |
| | | * 进程内还原开关,默认开启 |
| | | */ |
| | | @property (nonatomic) BOOL symbolicateInProcessEnable; |
| | | |
| | | /** |
| | | * 非正常退出事件记录开关,默认关闭 |
| | | */ |
| | | @property (nonatomic) BOOL unexpectedTerminatingDetectionEnable; |
| | | |
| | | /** |
| | | * 页面信息记录开关,默认开启 |
| | | */ |
| | | @property (nonatomic) BOOL viewControllerTrackingEnable; |
| | | |
| | | /** |
| | | * Bugly Delegate |
| | | */ |
| | | @property (nonatomic, assign) id<BuglyDelegate> delegate; |
| | | |
| | | /** |
| | | * 控制自定义日志上报,默认值为BuglyLogLevelSilent,即关闭日志记录功能。 |
| | | * 如果设置为BuglyLogLevelWarn,则在崩溃时会上报Warn、Error接口打印的日志 |
| | | */ |
| | | @property (nonatomic, assign) BuglyLogLevel reportLogLevel; |
| | | |
| | | /** |
| | | * 崩溃数据过滤器,如果崩溃堆栈的模块名包含过滤器中设置的关键字,则崩溃数据不会进行上报 |
| | | * 例如,过滤崩溃堆栈中包含搜狗输入法的数据,可以添加过滤器关键字SogouInputIPhone.dylib等 |
| | | */ |
| | | @property (nonatomic, copy) NSArray *excludeModuleFilter; |
| | | |
| | | /** |
| | | * 控制台日志上报开关,默认开启 |
| | | */ |
| | | @property (nonatomic, assign) BOOL consolelogEnable; |
| | | |
| | | @end |
| | | BLY_END_NONNULL |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: e6aaf5f7932de6b4aa98ba197082fcfc |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | // |
| | | // BuglyLog.h |
| | | // |
| | | // Copyright © 2017 tencent.com. All rights reserved. |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | // Log level for Bugly Log |
| | | typedef NS_ENUM(NSUInteger, BuglyLogLevel) { |
| | | BuglyLogLevelSilent = 0, |
| | | BuglyLogLevelError = 1, |
| | | BuglyLogLevelWarn = 2, |
| | | BuglyLogLevelInfo = 3, |
| | | BuglyLogLevelDebug = 4, |
| | | BuglyLogLevelVerbose = 5, |
| | | }; |
| | | #pragma mark - |
| | | |
| | | OBJC_EXTERN void BLYLog(BuglyLogLevel level, NSString *format, ...) NS_FORMAT_FUNCTION(2, 3); |
| | | |
| | | OBJC_EXTERN void BLYLogv(BuglyLogLevel level, NSString *format, va_list args) NS_FORMAT_FUNCTION(2, 0); |
| | | |
| | | #pragma mark - |
| | | #define BUGLY_LOG_MACRO(_level, fmt, ...) [BuglyLog level:_level tag:nil log:fmt, ##__VA_ARGS__] |
| | | |
| | | #define BLYLogError(fmt, ...) BUGLY_LOG_MACRO(BuglyLogLevelError, fmt, ##__VA_ARGS__) |
| | | #define BLYLogWarn(fmt, ...) BUGLY_LOG_MACRO(BuglyLogLevelWarn, fmt, ##__VA_ARGS__) |
| | | #define BLYLogInfo(fmt, ...) BUGLY_LOG_MACRO(BuglyLogLevelInfo, fmt, ##__VA_ARGS__) |
| | | #define BLYLogDebug(fmt, ...) BUGLY_LOG_MACRO(BuglyLogLevelDebug, fmt, ##__VA_ARGS__) |
| | | #define BLYLogVerbose(fmt, ...) BUGLY_LOG_MACRO(BuglyLogLevelVerbose, fmt, ##__VA_ARGS__) |
| | | |
| | | #pragma mark - Interface |
| | | @interface BuglyLog : NSObject |
| | | |
| | | /** |
| | | * @brief 初始化日志模块 |
| | | * |
| | | * @param level 设置默认日志级别,默认BLYLogLevelSilent |
| | | * |
| | | * @param printConsole 是否打印到控制台,默认NO |
| | | */ |
| | | + (void)initLogger:(BuglyLogLevel) level consolePrint:(BOOL)printConsole; |
| | | |
| | | /** |
| | | * @brief 打印BLYLogLevelInfo日志 |
| | | * |
| | | * @param format 日志内容 总日志大小限制为:字符串长度30k,条数200 |
| | | */ |
| | | + (void)log:(NSString *)format, ... NS_FORMAT_FUNCTION(1, 2); |
| | | |
| | | /** |
| | | * @brief 打印日志 |
| | | * |
| | | * @param level 日志级别 |
| | | * @param message 日志内容 总日志大小限制为:字符串长度30k,条数200 |
| | | */ |
| | | + (void)level:(BuglyLogLevel) level logs:(NSString *)message; |
| | | |
| | | /** |
| | | * @brief 打印日志 |
| | | * |
| | | * @param level 日志级别 |
| | | * @param format 日志内容 总日志大小限制为:字符串长度30k,条数200 |
| | | */ |
| | | + (void)level:(BuglyLogLevel) level log:(NSString *)format, ... NS_FORMAT_FUNCTION(2, 3); |
| | | |
| | | /** |
| | | * @brief 打印日志 |
| | | * |
| | | * @param level 日志级别 |
| | | * @param tag 日志模块分类 |
| | | * @param format 日志内容 总日志大小限制为:字符串长度30k,条数200 |
| | | */ |
| | | + (void)level:(BuglyLogLevel) level tag:(NSString *) tag log:(NSString *)format, ... NS_FORMAT_FUNCTION(3, 4); |
| | | |
| | | @end |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: fcdd1a254f5ac71439f64020d222765b |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 562250b44fe02cf4abbb1cb3bacd277d |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | framework module Bugly { |
| | | umbrella header "Bugly.h" |
| | | |
| | | export * |
| | | module * { export * } |
| | | |
| | | link framework "Foundation" |
| | | link framework "Security" |
| | | link framework "SystemConfiguration" |
| | | link "c++" |
| | | link "z" |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 30fee337aa477fb47988dc68e7f768a0 |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: f5434fa1f8a5c9546b1356756a3b2be7 |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | // |
| | | // BuglyBridge.h |
| | | // BuglyAgent |
| | | // |
| | | // Created by Yeelik on 15/11/25. |
| | | // Copyright © 2015年 Bugly. All rights reserved. |
| | | // |
| | | // Version: 1.3.3 |
| | | // |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | |
| | | #pragma mark - Interface for Bridge |
| | | |
| | | #ifdef __cplusplus |
| | | extern "C"{ |
| | | #endif |
| | | |
| | | /** |
| | | * @brief 初始化 |
| | | * |
| | | * @param appId 应用标识 |
| | | * @param debug 是否开启debug模式,开启后会在控制台打印调试信息,默认为NO |
| | | * @param level 自定义日志上报级别,使用SDK接口打印的日志会跟崩溃信息一起上报,默认为Info(即Info、Warning、Error级别的日志都会上报) |
| | | * Debug=4,Info=3,Warnning=2,Error=1,Off=0 |
| | | */ |
| | | void _BuglyInit(const char * appId, bool debug, int level); |
| | | |
| | | /** |
| | | * @brief 设置用户唯一标识 |
| | | * |
| | | * @param userId |
| | | */ |
| | | void _BuglySetUserId(const char * userId); |
| | | |
| | | /** |
| | | * @brief 设置自定义标签 |
| | | * |
| | | * @param tag |
| | | */ |
| | | void _BuglySetTag(int tag); |
| | | |
| | | /** |
| | | * @brief 设置自定义键值对数据 |
| | | * |
| | | * @param key |
| | | * @param value |
| | | */ |
| | | void _BuglySetKeyValue(const char * key, const char * value); |
| | | |
| | | /** |
| | | * @brief 自定义异常数据上报 |
| | | * |
| | | * @param type |
| | | * @param name 异常类型 |
| | | * @param reason 异常原因 |
| | | * @param stackTrace 异常堆栈 |
| | | * @param extras 附加数据 |
| | | * @param quit 上报后是否退出应用 |
| | | */ |
| | | void _BuglyReportException(int type, const char * name, const char * reason, const char * stackTrace, const char * extras, bool quit); |
| | | |
| | | /** |
| | | * @brief 设置默认的应用配置,在初始化之前调用 |
| | | * |
| | | * @param channel 渠道 |
| | | * @param version 应用版本 |
| | | * @param user 用户 |
| | | * @param deviceId 设备唯一标识 |
| | | */ |
| | | void _BuglyDefaultConfig(const char * channel, const char * version, const char *user, const char * deviceId); |
| | | |
| | | /** |
| | | * @brief 自定义日志打印接口 |
| | | * |
| | | * @param level 日志级别, 1=Error、2=Warning、3=Info、4=Debug |
| | | * @param tag 日志标签 |
| | | * @param log 日志内容 |
| | | */ |
| | | void _BuglyLogMessage(int level, const char * tag, const char * log); |
| | | |
| | | /** |
| | | * @brief 设置崩溃上报组件的类别 |
| | | * |
| | | * @param type 0=Default、1=Bugly、2=MSDK、3=IMSDK |
| | | */ |
| | | void _BuglyConfigCrashReporterType(int type); |
| | | |
| | | /** |
| | | * @brief 设置额外的配置信息 |
| | | * |
| | | * @param key |
| | | * @param value |
| | | */ |
| | | void _BuglySetExtraConfig(const char *key, const char * value); |
| | | |
| | | #ifdef __cplusplus |
| | | } // extern "C" |
| | | #endif |
| | | |
| | | #pragma mark - |
copy from Assets/Plugins/Android/libs/armeabi-v7a/libBugly.so.meta
copy to Assets/Plugins/BuglyPlugins/iOS/BuglyBridge/BuglyBridge.h.meta
File was copied from Assets/Plugins/Android/libs/armeabi-v7a/libBugly.so.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: c9cdbdcbc4b089a4790f80e22bad555a |
| | | guid: b55a69cc84ca47e44b62297cafc0804b |
| | | PluginImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | |
| | | validateReferences: 1 |
| | | platformData: |
| | | - first: |
| | | Android: Android |
| | | second: |
| | | enabled: 1 |
| | | settings: |
| | | CPU: ARMv7 |
| | | - first: |
| | | Any: |
| | | second: |
| | | enabled: 0 |
| | | enabled: 1 |
| | | settings: {} |
| | | - first: |
| | | Editor: Editor |
copy from Assets/Plugins/Android/libs/armeabi-v7a/libBugly.so.meta
copy to Assets/Plugins/BuglyPlugins/iOS/BuglyBridge/libBuglyBridge.a.meta
File was copied from Assets/Plugins/Android/libs/armeabi-v7a/libBugly.so.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: c9cdbdcbc4b089a4790f80e22bad555a |
| | | guid: 94596565f5e955f40aba3a64d7fbd324 |
| | | PluginImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | |
| | | validateReferences: 1 |
| | | platformData: |
| | | - first: |
| | | Android: Android |
| | | second: |
| | | enabled: 1 |
| | | settings: |
| | | CPU: ARMv7 |
| | | - first: |
| | | Any: |
| | | second: |
| | | enabled: 0 |
| | | enabled: 1 |
| | | settings: {} |
| | | - first: |
| | | Editor: Editor |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 0fcf672e672b6d445a6f745f9580af5a |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: a47b06b8f00d4384495519fb6cea4522 |
| | | folderAsset: yes |
| | | timeCreated: 1428752350 |
| | | licenseType: Store |
| | | DefaultImporter: |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 5560b1fc753e72f48a7d18797afe4658 |
| | | folderAsset: yes |
| | | timeCreated: 1428698914 |
| | | licenseType: Store |
| | | DefaultImporter: |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | //(c) 2016 Movinarc |
| | | //http://movinarc.com/unity-package-uninstaller |
| | | using UnityEngine; |
| | | using UnityEditor; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.IO; |
| | | using System.Linq; |
| | | using Microsoft.Win32; |
| | | using System.IO.Compression; |
| | | using System.Reflection; |
| | | |
| | | //SharpCompress: https://sharpcompress.codeplex.com/ |
| | | using SharpCompress; |
| | | using SharpCompress.Reader; |
| | | using SharpCompress.Common; |
| | | using System.Collections; |
| | | using System.ComponentModel; |
| | | |
| | | namespace Movinarc |
| | | { |
| | | public class PUManager : EditorWindow |
| | | { |
| | | Vector2 scrollPos = Vector2.zero; |
| | | Texture2D putitle = null; |
| | | Texture2D puicon = null; |
| | | Texture2D line = null; |
| | | Texture2D imgInfo; |
| | | Texture2D imgQuestion; |
| | | Texture2D openicon = null; |
| | | string customPackage = string.Empty; |
| | | GUIStyle horAlignStyle = null; |
| | | GUIStyle fontStyle = null; |
| | | GUIStyle[] searchStyles = null; |
| | | string searchText = ""; |
| | | List<Package> packages = null; |
| | | List<Package> assetStoreList = null; |
| | | Rect rectScrollView; |
| | | double lastTime = 0; |
| | | bool blinkOn = true; |
| | | string unityPath = ""; |
| | | string infoToShow = ""; |
| | | |
| | | struct Package |
| | | { |
| | | public string fullPath; |
| | | public string fileName; |
| | | public string dateString; |
| | | public DateTime date; |
| | | } |
| | | |
| | | public class AssetPath |
| | | { |
| | | public string name = ""; |
| | | public string filePath = ""; |
| | | public bool isDirectory = false; |
| | | } |
| | | |
| | | [MenuItem("Assets/Uninstall Package...")] |
| | | static void CreateWindow() |
| | | { |
| | | var win = EditorWindow.GetWindow(typeof(PUManager)); |
| | | win.minSize = new Vector2(410, 450); |
| | | win.titleContent.text = "Uninstall Package"; |
| | | win.titleContent.tooltip = "v1.3"; |
| | | win.Focus(); |
| | | } |
| | | |
| | | public void Update() |
| | | { |
| | | if (EditorApplication.timeSinceStartup - lastTime > .25) |
| | | { |
| | | blinkOn = !blinkOn; |
| | | lastTime = EditorApplication.timeSinceStartup; |
| | | Repaint(); |
| | | } |
| | | } |
| | | |
| | | public void OnGUI() |
| | | { |
| | | #region init |
| | | if (packages == null || packages.Count <= 0) |
| | | { |
| | | TreeView tv = CreateInstance<TreeView>(); |
| | | tv.allCheckedByDefault = true; |
| | | packages = new List<Package>(); |
| | | |
| | | #if UNITY_EDITOR_WIN |
| | | unityPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); |
| | | unityPath = Path.Combine(unityPath, "Unity"); |
| | | |
| | | #elif UNITY_EDITOR_OSX |
| | | |
| | | unityPath = System.Environment.GetFolderPath(Environment.SpecialFolder.Personal) + "/Library/Unity"; |
| | | #endif |
| | | var info = new DirectoryInfo(unityPath); |
| | | var files = info.GetFiles("*.unitypackage", SearchOption.AllDirectories); |
| | | foreach (var file in files) |
| | | { |
| | | packages.Add(new Package() |
| | | { fileName = Path.GetFileNameWithoutExtension(file.FullName), |
| | | fullPath = file.FullName, |
| | | date = file.CreationTime, dateString = file.CreationTime.ToString("g") |
| | | }); |
| | | } |
| | | packages = packages.OrderBy(i => i.fileName).ToList(); |
| | | assetStoreList = new List<Package>(packages); |
| | | |
| | | |
| | | putitle = Resources.Load("PU_title") as Texture2D; |
| | | puicon = Resources.Load("PU_icon") as Texture2D; |
| | | line = Resources.Load("pu_line") as Texture2D; |
| | | imgInfo = Resources.Load("pu_i") as Texture2D; |
| | | imgQuestion = Resources.Load("pu_q") as Texture2D; |
| | | |
| | | openicon = Resources.Load("Open_icon") as Texture2D; |
| | | horAlignStyle = new GUIStyle(); |
| | | horAlignStyle.padding = new RectOffset(0, 5, 15, 0); |
| | | |
| | | fontStyle = new GUIStyle(); |
| | | fontStyle.fontSize = 9; |
| | | fontStyle.normal.textColor = new Color(.2f, .2f, .2f); |
| | | fontStyle.padding = new RectOffset(5, 0, 5, 0); |
| | | fontStyle.wordWrap = true; |
| | | |
| | | |
| | | searchStyles = new GUIStyle[3]; |
| | | searchText = ""; |
| | | } |
| | | #endregion |
| | | |
| | | GUI.skin.label.alignment = TextAnchor.MiddleLeft; |
| | | GUILayout.Label(putitle); |
| | | #region Search/Select |
| | | searchStyles[0] = GUI.skin.FindStyle("Toolbar"); |
| | | searchStyles[1] = GUI.skin.FindStyle("ToolbarSeachTextField"); |
| | | searchStyles[2] = GUI.skin.FindStyle("ToolbarSeachCancelButton"); |
| | | |
| | | GUILayout.BeginHorizontal(); |
| | | GUILayout.Box("Search / Select ", GUILayout.ExpandWidth(true)); |
| | | GUILayout.Label(imgQuestion, GUILayout.ExpandWidth(false)); |
| | | var qrect = GUILayoutUtility.GetLastRect(); |
| | | if (qrect.Contains(Event.current.mousePosition)) |
| | | { |
| | | infoToShow = "[Search / Select] \nType the name of the package you are looking for to filter the list of packages."; |
| | | } |
| | | |
| | | GUILayout.EndHorizontal(); |
| | | |
| | | GUILayout.BeginHorizontal(searchStyles[0]); |
| | | GUI.SetNextControlName("txtSearch"); |
| | | searchText = GUILayout.TextField(searchText, searchStyles[1]); |
| | | |
| | | if (GUILayout.Button("", searchStyles[2])) |
| | | { |
| | | searchText = ""; |
| | | GUI.FocusControl(null); |
| | | } |
| | | |
| | | GUI.FocusControl("txtSearch"); |
| | | GUILayout.EndHorizontal(); |
| | | |
| | | GUILayout.Space(15.0f); |
| | | scrollPos = GUILayout.BeginScrollView(scrollPos, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true)); |
| | | GUILayout.BeginVertical(); |
| | | |
| | | if (assetStoreList != null && assetStoreList.Count > 0) |
| | | { |
| | | foreach (var item in assetStoreList) |
| | | { |
| | | GUILayout.BeginHorizontal(); |
| | | if (GUILayout.Button(new GUIContent(puicon, "Uninstall"), GUILayout.ExpandWidth(false))) |
| | | { |
| | | CheckUninstall(item.fullPath); |
| | | } |
| | | var irect = GUILayoutUtility.GetLastRect(); |
| | | irect.width = position.width; |
| | | if (irect.Contains(Event.current.mousePosition) && rectScrollView.Contains(Event.current.mousePosition)) |
| | | { |
| | | infoToShow = String.Format("[Name] {0}\n[Path] {1}\n[Downladed] {2}", item.fileName, item.fullPath, item.dateString); |
| | | } |
| | | GUILayout.Label(item.fileName, this.horAlignStyle, GUILayout.MinWidth(230)); |
| | | |
| | | |
| | | GUILayout.EndHorizontal(); |
| | | GUILayout.Space(5.0f); |
| | | GUILayout.Label(line); |
| | | } |
| | | } |
| | | |
| | | GUILayout.EndVertical(); |
| | | GUILayout.EndScrollView(); |
| | | if (Event.current.type == EventType.Repaint) |
| | | { |
| | | rectScrollView = GUILayoutUtility.GetLastRect(); |
| | | rectScrollView.x = scrollPos.x; |
| | | rectScrollView.y = scrollPos.y; |
| | | } |
| | | #endregion |
| | | |
| | | GUILayout.Space(10.0f); |
| | | |
| | | #region Browse |
| | | GUILayout.BeginHorizontal(); |
| | | GUILayout.Box("Browse ", GUILayout.ExpandWidth(true)); |
| | | GUILayout.Label(imgQuestion, GUILayout.ExpandWidth(false)); |
| | | qrect = GUILayoutUtility.GetLastRect(); |
| | | if (qrect.Contains(Event.current.mousePosition)) |
| | | { |
| | | infoToShow = "[Browse] \nClick Open to select a unity package file, from your computer. Then click uninstall to unimport the package."; |
| | | } |
| | | GUILayout.EndHorizontal(); |
| | | GUILayout.BeginHorizontal(); |
| | | |
| | | if (GUILayout.Button(new GUIContent(openicon, "Open"), GUILayout.ExpandWidth(false))) // Custom Open Button |
| | | { |
| | | var f = EditorUtility.OpenFilePanel("Select the .unitypackage file you are going to remove from project", "", "unitypackage"); |
| | | if (System.IO.File.Exists(f)) |
| | | { |
| | | this.customPackage = f; |
| | | } |
| | | } |
| | | if (string.IsNullOrEmpty(customPackage)) |
| | | GUI.enabled = false; |
| | | else |
| | | GUI.enabled = true; |
| | | if (GUILayout.Button(new GUIContent(puicon, "Uninstall"), GUILayout.ExpandWidth(false))) // Custom Uninstall Button |
| | | { |
| | | CheckUninstall(this.customPackage); |
| | | } |
| | | GUI.enabled = true; |
| | | GUILayout.BeginVertical(); |
| | | if (string.IsNullOrEmpty(customPackage)) |
| | | GUILayout.Label("---", horAlignStyle); |
| | | else |
| | | { |
| | | FileInfo fi = new FileInfo(customPackage); |
| | | var pkgName = Path.GetFileNameWithoutExtension(fi.FullName); |
| | | GUILayout.BeginHorizontal(); |
| | | GUILayout.Label(pkgName, this.horAlignStyle, GUILayout.ExpandWidth(true)); |
| | | GUILayout.EndHorizontal(); |
| | | var irect = GUILayoutUtility.GetLastRect(); |
| | | if (irect.Contains(Event.current.mousePosition)) |
| | | { |
| | | infoToShow = String.Format("[Name] {0}\n[Path] {1}\n[Downladed] {2}", pkgName, fi.FullName, fi.CreationTime.ToString("g")); |
| | | } |
| | | } |
| | | GUILayout.EndVertical(); |
| | | GUILayout.EndHorizontal(); |
| | | #endregion |
| | | |
| | | GUILayout.Space(10.0f); |
| | | GUILayout.Label(line, GUILayout.ExpandWidth(true)); |
| | | |
| | | if (GUI.changed) |
| | | { |
| | | FilterAssetStoreList(searchText); |
| | | } |
| | | GUILayout.BeginHorizontal(); |
| | | GUILayout.Label(imgInfo); |
| | | |
| | | if (!String.IsNullOrEmpty(infoToShow)) |
| | | { |
| | | GUILayout.Label(infoToShow, fontStyle, GUILayout.Height(70), GUILayout.ExpandWidth(true)); |
| | | } |
| | | else |
| | | { |
| | | GUILayout.Label("", fontStyle, GUILayout.Height(70), GUILayout.ExpandWidth(true)); |
| | | } |
| | | GUILayout.EndHorizontal(); |
| | | |
| | | } |
| | | |
| | | void FilterAssetStoreList(string what) |
| | | { |
| | | if (packages != null) |
| | | assetStoreList = packages.FindAll(x => x.fileName.ToLowerInvariant().Contains(what.ToLowerInvariant())); |
| | | } |
| | | |
| | | public void PrepareForUnimport(string file2import, string tempPath) |
| | | { |
| | | // test absolute |
| | | if (!File.Exists(file2import)) |
| | | { |
| | | // test relative |
| | | file2import = Path.Combine(Environment.CurrentDirectory, file2import); |
| | | if (!File.Exists(file2import)) |
| | | throw new FileNotFoundException(file2import); |
| | | } |
| | | |
| | | if (!file2import.ToLower().EndsWith(".unitypackage")) |
| | | throw new Exception("You must select *.unitypackage files."); |
| | | |
| | | if (!Directory.Exists(tempPath)) |
| | | Directory.CreateDirectory(tempPath); |
| | | |
| | | EditorUtility.DisplayProgressBar("Uninstalling Package", "Initializing...", .25f); |
| | | HolyGZip(file2import, tempPath); |
| | | |
| | | EditorUtility.DisplayProgressBar("Uninstalling Package", "Fetching Package Structure...", .5f); |
| | | List<AssetPath> fileList = GenerateAssetList(tempPath); |
| | | |
| | | |
| | | var assetList = AssetDatabase.GetAllAssetPaths().ToList(); |
| | | var foundList = new List<string>(); |
| | | foreach (var item in assetList) |
| | | { |
| | | if (fileList.Exists((f) => f.filePath.Equals(item, StringComparison.OrdinalIgnoreCase))) |
| | | { |
| | | foundList.Add(item); |
| | | } |
| | | } |
| | | var dirs = PUSelection.DirectoriesPathList(fileList); |
| | | |
| | | EditorUtility.ClearProgressBar(); |
| | | bool goOn = true; |
| | | if (foundList.Count <= 0) |
| | | { |
| | | if (!EditorUtility.DisplayDialog("No files found.", "It seems that '" + Path.GetFileNameWithoutExtension(file2import) + "' doesn't exist in your project. Do you want to continue anyway?", "Continue Anyway", "No")) |
| | | { |
| | | goOn = false; |
| | | PUSelection.RemoveMess(tempPath); |
| | | } |
| | | } |
| | | if (goOn) |
| | | { |
| | | PUSelection pus = ScriptableObject.CreateInstance<PUSelection>(); |
| | | pus.fileList = fileList; |
| | | pus.directories = dirs; |
| | | pus.foundList = foundList; |
| | | pus.packageName = Path.GetFileNameWithoutExtension(file2import); |
| | | pus.packagePath = file2import; |
| | | pus.tempPath = tempPath; |
| | | pus.titleContent = new GUIContent(""); |
| | | pus.minSize = new Vector2(300, 200); |
| | | |
| | | pus.ShowUtility(); |
| | | } |
| | | } |
| | | |
| | | void CheckUninstall(string customPackage) |
| | | { |
| | | try |
| | | { |
| | | |
| | | UninstallPackage(customPackage); |
| | | |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | EditorUtility.ClearProgressBar(); |
| | | Debug.LogError(ex.Message); |
| | | } |
| | | } |
| | | |
| | | public void UninstallPackage(string path) |
| | | { |
| | | string tempPath = Path.Combine(Path.GetTempPath(), "PU" + DateTime.Now.Ticks.ToString()); |
| | | |
| | | PrepareForUnimport(path, tempPath); |
| | | } |
| | | |
| | | public void HolyGZip(string gzipFileName, string targetDir) |
| | | { |
| | | using (Stream stream = File.OpenRead(gzipFileName)) |
| | | { |
| | | var reader = ReaderFactory.Open(stream); |
| | | var progress = .25f; |
| | | |
| | | while (reader.MoveToNextEntry()) |
| | | { |
| | | if (!reader.Entry.IsDirectory) |
| | | { |
| | | reader.WriteEntryToDirectory(targetDir, ExtractOptions.ExtractFullPath | ExtractOptions.Overwrite); |
| | | progress += .75f * reader.Entry.Size / stream.Length; |
| | | EditorUtility.DisplayProgressBar("Uninstalling Package", "Analysing... ", progress); |
| | | |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | private List<AssetPath> GenerateAssetList(string contentPath) |
| | | { |
| | | string appPath = Application.dataPath.Substring(0, Application.dataPath.LastIndexOf(@"Assets")); |
| | | var lst = new List<AssetPath>(); |
| | | var directoryInfo = new DirectoryInfo(contentPath).GetDirectories(); |
| | | foreach (var item in directoryInfo) |
| | | { |
| | | string pathnameFromFile = File.ReadAllLines(Path.Combine(item.FullName, "pathname")).ToList().First(); |
| | | //ensure path correction |
| | | pathnameFromFile = pathnameFromFile.Replace(@"\\", "/"); |
| | | pathnameFromFile = pathnameFromFile.Replace(@"\", "/"); |
| | | |
| | | var asset = new AssetPath(); |
| | | if (Directory.Exists(Path.Combine(appPath, pathnameFromFile))) |
| | | { |
| | | asset.name = Path.GetDirectoryName(pathnameFromFile); |
| | | |
| | | if (!pathnameFromFile.EndsWith("/")) |
| | | { |
| | | pathnameFromFile += "/"; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | asset.name = Path.GetFileName(pathnameFromFile); |
| | | } |
| | | asset.filePath = pathnameFromFile; |
| | | |
| | | lst.Add(asset); |
| | | } |
| | | var ordered = lst.OrderByDescending(i => i.filePath.Count(x => x == '/')); |
| | | |
| | | return ordered.ToList(); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 0461fb63d4418b84f837b99a3f5876d7 |
| | | timeCreated: 1429438135 |
| | | licenseType: Store |
| | | MonoImporter: |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using UnityEngine; |
| | | using System.Collections; |
| | | using UnityEditor; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.IO; |
| | | using System; |
| | | |
| | | namespace Movinarc |
| | | { |
| | | public class PUSelection : EditorWindow |
| | | { |
| | | |
| | | TreeView fileTree = null; |
| | | Texture2D fold1 = null; |
| | | Texture2D filepic = null; |
| | | Texture2D line = null; |
| | | GUIStyle boldStyle = null; |
| | | Rect rectScroll; |
| | | Vector2 scrollPos = Vector2.zero; |
| | | public List<PUManager.AssetPath> fileList; |
| | | public List<string> foundList; |
| | | public List<string> directories; |
| | | public string tempPath; |
| | | public string packageName = ""; |
| | | public string packagePath; |
| | | |
| | | public static List<string> DirectoriesPathList(List<PUManager.AssetPath> paths) |
| | | { |
| | | List<string> possibleDirs = new List<string>(); |
| | | List<TreeView.NodePath> files = new List<TreeView.NodePath>(); |
| | | paths.ForEach( |
| | | (p) => |
| | | { |
| | | var ph = TreeView.PathHierarchy(p.filePath); |
| | | foreach (var item in ph) |
| | | { |
| | | if (!possibleDirs.Exists((d) => d.Equals(item.path, System.StringComparison.OrdinalIgnoreCase)) && |
| | | !item.path.Equals(p.filePath, System.StringComparison.OrdinalIgnoreCase)) |
| | | { |
| | | possibleDirs.Add(item.path); |
| | | } |
| | | } |
| | | files.Add(new TreeView.NodePath(){ name = p.name, isDirectory = false, path = p.filePath }); |
| | | } |
| | | ); |
| | | return possibleDirs; |
| | | } |
| | | |
| | | void Awake() |
| | | { |
| | | boldStyle = new GUIStyle(GUI.skin.button); |
| | | boldStyle.fontStyle = FontStyle.Bold; |
| | | |
| | | } |
| | | |
| | | void OnGUI() |
| | | { |
| | | if (fileTree == null) |
| | | { |
| | | fileTree = ScriptableObject.CreateInstance<TreeView>(); |
| | | if (fileList != null) |
| | | { |
| | | fold1 = Resources.Load("pu_fold") as Texture2D; |
| | | filepic = Resources.Load("pu_file2") as Texture2D; |
| | | line = Resources.Load("pu_line") as Texture2D; |
| | | |
| | | fileList.ForEach((f) => fileTree.AddNodeFromPath(f.filePath, directories, foundList)); |
| | | rectScroll = new Rect(0, 0, this.position.width, 50); |
| | | } |
| | | fileTree.ParentalCheck(); |
| | | fileTree.EmptyFolderCheck(directories); |
| | | } |
| | | |
| | | GUILayout.Box(packageName, GUILayout.ExpandWidth(true)); |
| | | GUILayout.Label(line); |
| | | GUILayout.Label(""); |
| | | var rect = GUILayoutUtility.GetLastRect(); |
| | | if (fileList != null) |
| | | { |
| | | rectScroll.x = rect.x; |
| | | rectScroll.y = rect.y; |
| | | scrollPos = GUI.BeginScrollView(new Rect(rect.x, rect.y + rect.height, this.position.width - rect.x, this.position.height - rect.height - rect.y - 40), |
| | | scrollPos, |
| | | rectScroll); |
| | | fileTree.populateTree(fileTree.treeroot, ref rect, fold1, filepic); |
| | | |
| | | GUI.EndScrollView(); |
| | | if (rectScroll.width < rect.x) |
| | | rectScroll.width += rect.x; |
| | | if (rectScroll.height < rect.y) |
| | | rectScroll.height += rect.y; |
| | | |
| | | var recBtn = new Rect(5, this.position.height - 30, 50, 20); |
| | | if (GUI.Button(recBtn, "All")) |
| | | { |
| | | fileTree.checkAll(fileTree.treeroot, true); |
| | | } |
| | | recBtn.x += 55; |
| | | if (GUI.Button(recBtn, "None")) |
| | | { |
| | | fileTree.checkNone(fileTree.treeroot); |
| | | } |
| | | recBtn.x = this.position.width - 130; |
| | | if (GUI.Button(recBtn, "Cancel")) |
| | | { |
| | | if (Directory.Exists(this.tempPath)) |
| | | RemoveMess(this.tempPath); |
| | | this.Close(); |
| | | } |
| | | recBtn.x = this.position.width - 75; |
| | | recBtn.width = 70; |
| | | if (fileTree.selectedNodes != null && fileTree.selectedNodes.Count > 0) |
| | | GUI.enabled = true; |
| | | else |
| | | GUI.enabled = false; |
| | | if (GUI.Button(recBtn, "Uninstall", boldStyle)) |
| | | { |
| | | Uninstall(this.packagePath); |
| | | |
| | | } |
| | | if (position.width < rect.x) |
| | | position = new Rect(position.x, position.y, rect.x + 30, position.height); |
| | | } |
| | | } |
| | | |
| | | void OnInspectorUpdate() |
| | | { |
| | | Repaint(); |
| | | } |
| | | |
| | | void Uninstall(string customPackage) |
| | | { |
| | | ClearWarnings(); |
| | | var fileName = System.IO.Path.GetFileNameWithoutExtension(customPackage); |
| | | if (EditorUtility.DisplayDialog("Delete Imported Unitypackage", string.Format("You're about to uninstall the '{0}'. Are you sure you want to delete all the files related to this package?", fileName), |
| | | "Yes", "No")) |
| | | { |
| | | try |
| | | { |
| | | if (EditorUtility.DisplayDialog("Delete Imported Unitypackage", string.Format("The operation can not be undone! Are you sure?"), "Yes. Do It!", "No")) |
| | | { |
| | | int delCnt = RemoveFiles(fileTree.selectedNodes); |
| | | |
| | | EditorUtility.DisplayProgressBar("Uninstalling Package", "Finalizing...", 1f); |
| | | if (Directory.Exists(this.tempPath)) |
| | | RemoveMess(this.tempPath); |
| | | |
| | | EditorUtility.ClearProgressBar(); |
| | | string msg = string.Format("{0} files/folders related to '{1}' deleted from project.", delCnt, fileName); |
| | | if (EditorUtility.DisplayDialog("Package Uninstaller", msg, "Ok")) |
| | | { |
| | | Debug.Log(msg); |
| | | EditorWindow.GetWindow(typeof(PUSelection)).Close(); |
| | | } |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | EditorUtility.ClearProgressBar(); |
| | | Debug.LogError(ex.Message); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private int RemoveFiles(List<TreeNode> filelist) |
| | | { |
| | | float step = .5f / filelist.Count; |
| | | float progress = .5f + step; |
| | | var dirs = new List<string>(); |
| | | int deleted = 0; |
| | | string appPath = Application.dataPath.Substring(0, Application.dataPath.LastIndexOf(@"Assets")); |
| | | |
| | | GC.Collect(); |
| | | GC.WaitForPendingFinalizers(); |
| | | foreach (var f in filelist) |
| | | { |
| | | |
| | | EditorUtility.DisplayProgressBar("Uninstalling Package", string.Format("Removing {0}", f.name), progress); |
| | | progress += step; |
| | | try |
| | | { |
| | | string fullPath = Path.Combine(appPath, f.path); |
| | | |
| | | var phList = TreeView.PathHierarchy(f.path); |
| | | phList.ForEach((ph) => |
| | | { |
| | | if (!dirs.Exists(d => d.Equals(ph.path, StringComparison.OrdinalIgnoreCase))) |
| | | dirs.Add(ph.path); |
| | | }); |
| | | |
| | | if (File.Exists(fullPath)) |
| | | { |
| | | File.Delete(fullPath); |
| | | deleted++; |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.LogError(ex.Message); |
| | | |
| | | } |
| | | finally |
| | | { |
| | | try |
| | | { |
| | | //deleting meta file |
| | | string fullPath = Path.Combine(appPath, f.path); |
| | | var meta = fullPath + ".meta"; |
| | | if (File.Exists(meta)) |
| | | File.Delete(meta); |
| | | GC.Collect(); |
| | | GC.WaitForPendingFinalizers(); |
| | | } |
| | | catch |
| | | { |
| | | } |
| | | } |
| | | } |
| | | dirs = dirs.OrderByDescending(i => i.Count(x => x == '/')).ToList(); |
| | | foreach (var item in dirs) |
| | | { |
| | | var fullpath = Path.Combine(appPath, item); |
| | | try |
| | | { |
| | | //deleted += (AssetDatabase.DeleteAsset(item) ? 1 : 0); |
| | | if (Directory.Exists(fullpath)) |
| | | { |
| | | if (Directory.GetFiles(fullpath).Length <= 0) |
| | | { |
| | | Directory.Delete(fullpath); |
| | | deleted++; |
| | | } |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.LogError(ex.Message); |
| | | } |
| | | finally |
| | | { |
| | | try |
| | | { |
| | | var meta = fullpath + ".meta"; |
| | | if (File.Exists(meta)) |
| | | File.Delete(meta); |
| | | } |
| | | catch |
| | | { |
| | | } |
| | | } |
| | | } |
| | | AssetDatabase.Refresh(); |
| | | return deleted; |
| | | } |
| | | |
| | | public static void RemoveMess(string tempPath) |
| | | { |
| | | try |
| | | { |
| | | var tempPathInfo = new DirectoryInfo(tempPath); |
| | | |
| | | foreach (FileInfo file in tempPathInfo.GetFiles()) |
| | | { |
| | | file.Delete(); |
| | | } |
| | | foreach (DirectoryInfo dir in tempPathInfo.GetDirectories()) |
| | | { |
| | | dir.Delete(true); |
| | | } |
| | | if (Directory.GetFiles(tempPath).Length <= 0) |
| | | Directory.Delete(tempPath); |
| | | } |
| | | catch |
| | | { |
| | | } |
| | | } |
| | | |
| | | private void GetDirectoryNames(string path, List<string> list) |
| | | { |
| | | var parent = Path.GetDirectoryName(path); |
| | | if (!string.IsNullOrEmpty(parent) && !list.Contains(parent.ToLower()) && string.Compare(parent, "assets", true) != 0) |
| | | { |
| | | list.Add(parent.ToLower()); |
| | | if (path.Contains("/")) |
| | | { |
| | | GetDirectoryNames(parent, list); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public static void ClearWarnings() |
| | | { |
| | | var logs = System.Type.GetType("UnityEditor.LogEntries, UnityEditor.dll"); |
| | | var clear = logs.GetMethod("Clear", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public); |
| | | clear.Invoke(null, null); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: ccb5b2dc839654498a9fbc2bc0bec2d7 |
| | | timeCreated: 1450976736 |
| | | licenseType: Store |
| | | MonoImporter: |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 8d084312fe5e9a648826a604e999688c |
| | | timeCreated: 1428871393 |
| | | licenseType: Store |
| | | PluginImporter: |
| | | serializedVersion: 1 |
| | | iconMap: {} |
| | | executionOrder: {} |
| | | isPreloaded: 0 |
| | | platformData: |
| | | Any: |
| | | enabled: 0 |
| | | settings: {} |
| | | Editor: |
| | | enabled: 1 |
| | | settings: |
| | | DefaultValueInitialized: true |
| | | WindowsStoreApps: |
| | | enabled: 0 |
| | | settings: |
| | | CPU: AnyCPU |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using UnityEngine; |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | using UnityEditor; |
| | | using System; |
| | | using System.IO; |
| | | using System.Linq; |
| | | |
| | | namespace Movinarc |
| | | { |
| | | public class TreeNode |
| | | { |
| | | public TreeNode() |
| | | { |
| | | children = new List<TreeNode>(); |
| | | lastCheckedState = isChecked; |
| | | } |
| | | //dynamic |
| | | public TreeNode root; |
| | | |
| | | public bool isTreeEmpty |
| | | { |
| | | get |
| | | { |
| | | return root.children == null || root.children.Count <= 0; |
| | | } |
| | | } |
| | | |
| | | public bool isExpanded = false; |
| | | public bool isRoot = false; |
| | | |
| | | public TreeNode parent; |
| | | public string name; |
| | | public bool isChecked; |
| | | public bool lastCheckedState; |
| | | //Primary Key - dynamic |
| | | public string path; |
| | | |
| | | //dynamic |
| | | public bool isDirectory; |
| | | |
| | | public List<TreeNode> children; |
| | | |
| | | public List<string> pathList() |
| | | { |
| | | return new List<string>(path.Split(new []{ '/' }, System.StringSplitOptions.RemoveEmptyEntries)); |
| | | } |
| | | |
| | | public List<string> pathList(string path) |
| | | { |
| | | return new List<string>(path.Split(new []{ '/' }, System.StringSplitOptions.RemoveEmptyEntries)); |
| | | } |
| | | |
| | | public List<TreeNode> parents |
| | | { |
| | | get |
| | | { |
| | | return new List<TreeNode>(getParents(this)); |
| | | } |
| | | } |
| | | |
| | | private IEnumerable<TreeNode> getParents(TreeNode node) |
| | | { |
| | | if (parent != null) |
| | | { |
| | | yield return parent; |
| | | getParents(parent); |
| | | } |
| | | } |
| | | |
| | | public TreeNode AddNode(TreeNode node) |
| | | { |
| | | children.Add(node); |
| | | return node; |
| | | } |
| | | |
| | | public TreeNode AddNode(string name, bool isChecked) |
| | | { |
| | | TreeNode node = new TreeNode(); |
| | | node.parent = this; |
| | | node.name = name; |
| | | node.isChecked = isChecked; |
| | | node.lastCheckedState = isChecked; |
| | | children.Add(node); |
| | | return node; |
| | | } |
| | | |
| | | bool Exists() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | public bool PathExists(string path) |
| | | { |
| | | return checkPathExists(pathList(path), root); |
| | | } |
| | | |
| | | private bool checkPathExists(List<string> pathList, TreeNode fromNode) |
| | | { |
| | | if (pathList != null) |
| | | { |
| | | if (pathList.Count > 0) |
| | | { |
| | | if (isTreeEmpty) |
| | | return false; |
| | | foreach (var ch in fromNode.children) |
| | | { |
| | | string n0 = pathList[0]; |
| | | if (ch.name.Equals(n0, StringComparison.OrdinalIgnoreCase)) |
| | | { |
| | | pathList.RemoveAt(0); |
| | | return checkPathExists(pathList, ch); |
| | | |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | if (pathList.Count == 0) |
| | | return true; |
| | | else |
| | | return false; |
| | | } |
| | | |
| | | public TreeNode GetNodeInPath(string path, TreeNode root) |
| | | { |
| | | return checkGetNodeInPath(pathList(path), root); |
| | | } |
| | | |
| | | private TreeNode checkGetNodeInPath(List<string> pathList, TreeNode fromNode) |
| | | { |
| | | |
| | | if (pathList != null) |
| | | { |
| | | if (pathList.Count > 0) |
| | | { |
| | | string n0 = pathList[0]; |
| | | |
| | | foreach (var child in fromNode.children) |
| | | { |
| | | if (child.name.Equals(n0, StringComparison.OrdinalIgnoreCase)) |
| | | { |
| | | pathList.RemoveAt(0); |
| | | return checkGetNodeInPath(pathList, child); |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | if (pathList.Count == 0) |
| | | return fromNode; |
| | | else |
| | | return null; |
| | | } |
| | | |
| | | public TreeNode GetParentNodeInPath(string path, TreeNode root) |
| | | { |
| | | return checkGetParentNodeInPath(pathList(path), root); |
| | | } |
| | | |
| | | private TreeNode checkGetParentNodeInPath(List<string> pathList, TreeNode fromNode) |
| | | { |
| | | |
| | | if (pathList != null) |
| | | { |
| | | if (pathList.Count > 0) |
| | | { |
| | | pathList.RemoveAt(pathList.Count - 1); |
| | | return GetNodeInPath(listToPath(pathList), fromNode); |
| | | } |
| | | } |
| | | return root; |
| | | } |
| | | |
| | | public static string listToPath(List<string> list) |
| | | { |
| | | string joint = String.Join("/", list.ToArray()); |
| | | joint = iHateSlashes(joint); |
| | | return joint; |
| | | } |
| | | |
| | | public static string iHateSlashes(string which) |
| | | { |
| | | if (which.Length > 0) |
| | | { |
| | | if (which[which.Length - 1] == '/') |
| | | which = which.Remove(which.Length - 1); |
| | | if (which[0] == '/') |
| | | which = which.Remove(0); |
| | | } |
| | | return which; |
| | | } |
| | | |
| | | public bool ExistsInChildren(string name, bool recursive) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | public List<TreeNode> FindByName(string name) |
| | | { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 2d7b6167c02c64c1bb262f81fb2d6e14 |
| | | timeCreated: 1451095332 |
| | | licenseType: Store |
| | | MonoImporter: |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using UnityEngine; |
| | | using UnityEditor; |
| | | using System; |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | using System.IO; |
| | | using System.Linq; |
| | | |
| | | namespace Movinarc |
| | | { |
| | | public class TreeView : EditorWindow |
| | | { |
| | | public TreeNode treenode; |
| | | public TreeNode treeroot; |
| | | public List<TreeNode> selectedNodes; |
| | | |
| | | public class NodePath |
| | | { |
| | | public TreeNode parent; |
| | | public string path; |
| | | public string name; |
| | | public bool isDirectory; |
| | | } |
| | | |
| | | public TreeView() |
| | | { |
| | | treenode = new TreeNode(); |
| | | selectedNodes = new List<TreeNode>(); |
| | | insertRoot(); |
| | | } |
| | | |
| | | public bool allCheckedByDefault = true; |
| | | public bool allExpandedByDefault = true; |
| | | |
| | | /// <summary> |
| | | /// Adds the node from path. |
| | | /// </summary> |
| | | /// <param name="path">Path.</param> |
| | | /// <param name = "dirList"></param> |
| | | public void AddNodeFromPath(string path, List<string> dirList, List<string> foundList) |
| | | { |
| | | var ph = PathHierarchy(path); |
| | | for (int i = 0; i < ph.Count; i++) |
| | | { |
| | | var p = ph[i]; |
| | | if (!treenode.PathExists(p.path)) |
| | | { |
| | | TreeNode pathParent = treenode.GetParentNodeInPath(p.path, treeroot); |
| | | TreeNode node = new TreeNode(); |
| | | node.parent = pathParent; |
| | | node.name = p.name; |
| | | node.path = TreeNode.iHateSlashes(p.path); |
| | | node.isDirectory = dirList.Exists((d) => d.Equals(node.path, StringComparison.OrdinalIgnoreCase)); |
| | | node.isChecked = foundList.Exists(f => f.Equals(node.path, StringComparison.OrdinalIgnoreCase)) && allCheckedByDefault; |
| | | node.lastCheckedState = node.isChecked; |
| | | if (node.isChecked) |
| | | selectedNodes.Add(node); |
| | | node.isExpanded = allExpandedByDefault; |
| | | pathParent.AddNode(node); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public void ParentalCheck() |
| | | { |
| | | foreach (var node in selectedNodes) |
| | | { |
| | | doParentalCheck(node); |
| | | } |
| | | } |
| | | |
| | | private void doParentalCheck(TreeNode node) |
| | | { |
| | | if (node.isDirectory && node.children.Count == 0) |
| | | { |
| | | node.isChecked = true; |
| | | node.lastCheckedState = true; |
| | | } |
| | | if (node.isChecked && node.parent != null) |
| | | { |
| | | node.parent.isChecked = true; |
| | | node.parent.lastCheckedState = true; |
| | | doParentalCheck(node.parent); |
| | | } |
| | | } |
| | | |
| | | public void EmptyFolderCheck(List<string> dirs) |
| | | { |
| | | var all = AssetDatabase.GetAllAssetPaths().ToList(); |
| | | var dirGuids = new List<string>(); |
| | | dirs.ForEach(d => dirGuids.Add(AssetDatabase.AssetPathToGUID(d))); |
| | | foreach (var node in treeroot.children) |
| | | { |
| | | doEmptyFolderCheck(node, dirGuids, all); |
| | | } |
| | | } |
| | | |
| | | private void doEmptyFolderCheck(TreeNode node, List<string> dirs, List<string> all) |
| | | { |
| | | if (node.isDirectory) |
| | | { |
| | | |
| | | //UnityEditor |
| | | var found = AssetDatabase.FindAssets("", new[] { node.path }).ToList(); |
| | | PUSelection.ClearWarnings(); |
| | | if (!found.Except(dirs).Any() && all.Exists(a => a.Equals(node.path, StringComparison.OrdinalIgnoreCase))) |
| | | { |
| | | node.isChecked = true; |
| | | node.lastCheckedState = true; |
| | | } |
| | | foreach (var child in node.children) |
| | | { |
| | | doEmptyFolderCheck(child, dirs, all); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public void populateTree(TreeNode node, ref Rect position, Texture2D foldIcon = null, Texture2D fileIcon = null) |
| | | { |
| | | if (!node.isRoot) |
| | | { |
| | | var content = new GUIContent(); |
| | | content.text = node.name; |
| | | if (node != null && node.path != null) |
| | | position.x = 5 + 15 * node.path.Split('/').Length; |
| | | if (node.isChecked) |
| | | { |
| | | |
| | | } |
| | | if (node.isDirectory) |
| | | { |
| | | position.width = 15; |
| | | node.isExpanded = EditorGUI.Foldout(position, node.isExpanded, ""); |
| | | position.x += 15; |
| | | position.width = 500; |
| | | node.isChecked = GUI.Toggle(position, node.isChecked, foldIcon); |
| | | position.x += 15; |
| | | |
| | | |
| | | } |
| | | else //is file |
| | | { |
| | | position.x += 15; |
| | | node.isChecked = GUI.Toggle(position, node.isChecked, fileIcon); |
| | | position.x += 15; |
| | | } |
| | | position.width = 500; |
| | | position.x += 15; |
| | | var lblStyle = EditorStyles.label; |
| | | if (node.isChecked) |
| | | { |
| | | lblStyle = EditorStyles.boldLabel; |
| | | if (!selectedNodes.Contains(node)) |
| | | { |
| | | selectedNodes.Add(node); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | if (selectedNodes.Contains(node)) |
| | | { |
| | | selectedNodes.Remove(node); |
| | | } |
| | | } |
| | | GUI.Label(position, node.name, lblStyle); |
| | | if (node.lastCheckedState != node.isChecked) |
| | | { |
| | | node.lastCheckedState = node.isChecked; |
| | | checkChildren(node); |
| | | } |
| | | position.y += position.height; |
| | | } |
| | | |
| | | if (node.isExpanded) |
| | | foreach (var child in node.children) |
| | | { |
| | | position.x += 15; |
| | | populateTree(child, ref position, foldIcon, fileIcon); |
| | | } |
| | | |
| | | } |
| | | |
| | | void checkChildren(TreeNode node) |
| | | { |
| | | foreach (var child in node.children) |
| | | { |
| | | child.isChecked = node.isChecked; |
| | | if (child.children != null && child.children.Count > 0) |
| | | checkChildren(child); |
| | | } |
| | | } |
| | | |
| | | public void checkAll(TreeNode node, bool all) |
| | | { |
| | | foreach (var item in node.children) |
| | | { |
| | | item.isChecked = all; |
| | | item.lastCheckedState = !all; |
| | | if (item.children != null && item.children.Count > 0) |
| | | checkChildren(item); |
| | | } |
| | | } |
| | | |
| | | public void checkNone(TreeNode node) |
| | | { |
| | | checkAll(node, false); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// Paths the hierarchy. |
| | | /// in: |
| | | /// Assets/1/2/3 |
| | | /// |
| | | /// out: |
| | | /// Assets |
| | | /// Assets/1 |
| | | /// Assets/1/2 |
| | | /// Assets/1/2/3 |
| | | /// </summary> |
| | | /// <param name="path">Path.</param> |
| | | public static List<NodePath> PathHierarchy(string path) |
| | | { |
| | | var ph = getPathHierarchy(path, new List<NodePath>()); |
| | | ph.Reverse(); |
| | | return ph; |
| | | } |
| | | |
| | | static List<NodePath> getPathHierarchy(string path, List<NodePath> lst) |
| | | { |
| | | List<string> pl = new List<string>(path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries)); |
| | | if (pl.Count > 0) |
| | | { |
| | | lst.Add(new NodePath() { path = path, name = pl[pl.Count - 1] }); |
| | | pl.RemoveAt(pl.Count - 1); |
| | | string joined = TreeNode.listToPath(pl); |
| | | getPathHierarchy(joined, lst); |
| | | } |
| | | return lst; |
| | | } |
| | | |
| | | private void insertRoot() |
| | | { |
| | | TreeNode root = new TreeNode(); |
| | | root.name = ""; |
| | | root.parent = null; |
| | | root.isRoot = true; |
| | | root.root = null; |
| | | root.isExpanded = true; |
| | | root.isChecked = true; |
| | | treenode.AddNode(root); |
| | | treeroot = root; |
| | | treenode.root = treeroot; |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: b8af78ecf2ff5412899ebae776c9686e |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | Package Uninstaller v1.3 |
| | | (c) 2018 Movinarc |
| | | |
| | | // ABOUT ====================================== |
| | | |
| | | This plugin helps you remove and cleanup any assets you have imported, from your project. You no longer need to remove files one by one. |
| | | |
| | | |
| | | // USAGE ====================================== |
| | | |
| | | - Goto "Assets/Uninstall Package..." |
| | | - Select from the list of the assets you have already imported from Asset Store or open the package you want to remove from your hard disk. |
| | | - Click "Uninstall" to open the file selector window. |
| | | - Choose the contents you want to keep or remove. |
| | | |
| | | |
| | | // LINKS ====================================== |
| | | |
| | | Forum Thread: https://forum.unity.com/threads/unity-package-uninstaller.378829 |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 17007f94b9fc24b94be74675b87d991f |
| | | timeCreated: 1451754113 |
| | | licenseType: Store |
| | | TextScriptImporter: |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 4848ffd6861a79c468aae2470abb7ea9 |
| | | folderAsset: yes |
| | | timeCreated: 1429802533 |
| | | licenseType: Store |
| | | DefaultImporter: |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 8a2a83217696b8b4a806c4940dcab8ca |
| | | TextureImporter: |
| | | internalIDToNameTable: [] |
| | | externalObjects: {} |
| | | serializedVersion: 11 |
| | | mipmaps: |
| | | mipMapMode: 0 |
| | | enableMipMap: 0 |
| | | sRGBTexture: 1 |
| | | linearTexture: 0 |
| | | fadeOut: 0 |
| | | borderMipMap: 0 |
| | | mipMapsPreserveCoverage: 0 |
| | | alphaTestReferenceValue: 0.5 |
| | | mipMapFadeDistanceStart: 1 |
| | | mipMapFadeDistanceEnd: 3 |
| | | bumpmap: |
| | | convertToNormalMap: 0 |
| | | externalNormalMap: 0 |
| | | heightScale: 0.25 |
| | | normalMapFilter: 0 |
| | | isReadable: 0 |
| | | streamingMipmaps: 0 |
| | | streamingMipmapsPriority: 0 |
| | | grayScaleToAlpha: 0 |
| | | generateCubemap: 6 |
| | | cubemapConvolution: 0 |
| | | seamlessCubemap: 0 |
| | | textureFormat: -2 |
| | | maxTextureSize: 2048 |
| | | textureSettings: |
| | | serializedVersion: 2 |
| | | filterMode: -1 |
| | | aniso: -1 |
| | | mipBias: -100 |
| | | wrapU: 1 |
| | | wrapV: 1 |
| | | wrapW: 1 |
| | | nPOTScale: 0 |
| | | lightmap: 0 |
| | | compressionQuality: 50 |
| | | spriteMode: 1 |
| | | spriteExtrude: 1 |
| | | spriteMeshType: 1 |
| | | alignment: 0 |
| | | spritePivot: {x: 0.5, y: 0.5} |
| | | spritePixelsToUnits: 100 |
| | | spriteBorder: {x: 0, y: 0, z: 0, w: 0} |
| | | spriteGenerateFallbackPhysicsShape: 1 |
| | | alphaUsage: 1 |
| | | alphaIsTransparency: 1 |
| | | spriteTessellationDetail: -1 |
| | | textureType: 8 |
| | | textureShape: 1 |
| | | singleChannelComponent: 0 |
| | | maxTextureSizeSet: 0 |
| | | compressionQualitySet: 0 |
| | | textureFormatSet: 0 |
| | | applyGammaDecoding: 1 |
| | | platformSettings: |
| | | - serializedVersion: 3 |
| | | buildTarget: DefaultTexturePlatform |
| | | maxTextureSize: 2048 |
| | | resizeAlgorithm: 0 |
| | | textureFormat: -1 |
| | | textureCompression: 1 |
| | | compressionQuality: 50 |
| | | crunchedCompression: 0 |
| | | allowsAlphaSplitting: 0 |
| | | overridden: 0 |
| | | androidETC2FallbackOverride: 0 |
| | | forceMaximumCompressionQuality_BC6H_BC7: 0 |
| | | spriteSheet: |
| | | serializedVersion: 2 |
| | | sprites: [] |
| | | outline: [] |
| | | physicsShape: [] |
| | | bones: [] |
| | | spriteID: 5e97eb03825dee720800000000000000 |
| | | internalID: 0 |
| | | vertices: [] |
| | | indices: |
| | | edges: [] |
| | | weights: [] |
| | | secondaryTextures: [] |
| | | spritePackingTag: |
| | | pSDRemoveMatte: 0 |
| | | pSDShowRemoveMatteOption: 0 |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 00aa186c03606459a87b8c001a1e1625 |
| | | TextureImporter: |
| | | internalIDToNameTable: [] |
| | | externalObjects: {} |
| | | serializedVersion: 11 |
| | | mipmaps: |
| | | mipMapMode: 0 |
| | | enableMipMap: 0 |
| | | sRGBTexture: 1 |
| | | linearTexture: 0 |
| | | fadeOut: 0 |
| | | borderMipMap: 0 |
| | | mipMapsPreserveCoverage: 0 |
| | | alphaTestReferenceValue: 0.5 |
| | | mipMapFadeDistanceStart: 1 |
| | | mipMapFadeDistanceEnd: 3 |
| | | bumpmap: |
| | | convertToNormalMap: 0 |
| | | externalNormalMap: 0 |
| | | heightScale: 0.25 |
| | | normalMapFilter: 0 |
| | | isReadable: 0 |
| | | streamingMipmaps: 0 |
| | | streamingMipmapsPriority: 0 |
| | | grayScaleToAlpha: 0 |
| | | generateCubemap: 6 |
| | | cubemapConvolution: 0 |
| | | seamlessCubemap: 0 |
| | | textureFormat: -1 |
| | | maxTextureSize: 2048 |
| | | textureSettings: |
| | | serializedVersion: 2 |
| | | filterMode: -1 |
| | | aniso: -1 |
| | | mipBias: -100 |
| | | wrapU: 1 |
| | | wrapV: 1 |
| | | wrapW: 1 |
| | | nPOTScale: 0 |
| | | lightmap: 0 |
| | | compressionQuality: 50 |
| | | spriteMode: 1 |
| | | spriteExtrude: 1 |
| | | spriteMeshType: 1 |
| | | alignment: 0 |
| | | spritePivot: {x: 0.5, y: 0.5} |
| | | spritePixelsToUnits: 100 |
| | | spriteBorder: {x: 0, y: 0, z: 0, w: 0} |
| | | spriteGenerateFallbackPhysicsShape: 1 |
| | | alphaUsage: 1 |
| | | alphaIsTransparency: 1 |
| | | spriteTessellationDetail: -1 |
| | | textureType: 8 |
| | | textureShape: 1 |
| | | singleChannelComponent: 0 |
| | | maxTextureSizeSet: 0 |
| | | compressionQualitySet: 0 |
| | | textureFormatSet: 0 |
| | | applyGammaDecoding: 1 |
| | | platformSettings: |
| | | - serializedVersion: 3 |
| | | buildTarget: DefaultTexturePlatform |
| | | maxTextureSize: 2048 |
| | | resizeAlgorithm: 0 |
| | | textureFormat: -1 |
| | | textureCompression: 1 |
| | | compressionQuality: 50 |
| | | crunchedCompression: 0 |
| | | allowsAlphaSplitting: 0 |
| | | overridden: 0 |
| | | androidETC2FallbackOverride: 0 |
| | | forceMaximumCompressionQuality_BC6H_BC7: 0 |
| | | spriteSheet: |
| | | serializedVersion: 2 |
| | | sprites: [] |
| | | outline: [] |
| | | physicsShape: [] |
| | | bones: [] |
| | | spriteID: 5e97eb03825dee720800000000000000 |
| | | internalID: 0 |
| | | vertices: [] |
| | | indices: |
| | | edges: [] |
| | | weights: [] |
| | | secondaryTextures: [] |
| | | spritePackingTag: |
| | | pSDRemoveMatte: 0 |
| | | pSDShowRemoveMatteOption: 0 |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: bd982337f615e459f8163ed5c7e39ffe |
| | | TextureImporter: |
| | | internalIDToNameTable: [] |
| | | externalObjects: {} |
| | | serializedVersion: 11 |
| | | mipmaps: |
| | | mipMapMode: 0 |
| | | enableMipMap: 0 |
| | | sRGBTexture: 1 |
| | | linearTexture: 0 |
| | | fadeOut: 0 |
| | | borderMipMap: 0 |
| | | mipMapsPreserveCoverage: 0 |
| | | alphaTestReferenceValue: 0.5 |
| | | mipMapFadeDistanceStart: 1 |
| | | mipMapFadeDistanceEnd: 3 |
| | | bumpmap: |
| | | convertToNormalMap: 0 |
| | | externalNormalMap: 0 |
| | | heightScale: 0.25 |
| | | normalMapFilter: 0 |
| | | isReadable: 0 |
| | | streamingMipmaps: 0 |
| | | streamingMipmapsPriority: 0 |
| | | grayScaleToAlpha: 0 |
| | | generateCubemap: 6 |
| | | cubemapConvolution: 0 |
| | | seamlessCubemap: 0 |
| | | textureFormat: -1 |
| | | maxTextureSize: 2048 |
| | | textureSettings: |
| | | serializedVersion: 2 |
| | | filterMode: -1 |
| | | aniso: -1 |
| | | mipBias: -100 |
| | | wrapU: 1 |
| | | wrapV: 1 |
| | | wrapW: 1 |
| | | nPOTScale: 0 |
| | | lightmap: 0 |
| | | compressionQuality: 50 |
| | | spriteMode: 1 |
| | | spriteExtrude: 1 |
| | | spriteMeshType: 1 |
| | | alignment: 0 |
| | | spritePivot: {x: 0.5, y: 0.5} |
| | | spritePixelsToUnits: 100 |
| | | spriteBorder: {x: 0, y: 0, z: 0, w: 0} |
| | | spriteGenerateFallbackPhysicsShape: 1 |
| | | alphaUsage: 1 |
| | | alphaIsTransparency: 1 |
| | | spriteTessellationDetail: -1 |
| | | textureType: 8 |
| | | textureShape: 1 |
| | | singleChannelComponent: 0 |
| | | maxTextureSizeSet: 0 |
| | | compressionQualitySet: 0 |
| | | textureFormatSet: 0 |
| | | applyGammaDecoding: 1 |
| | | platformSettings: |
| | | - serializedVersion: 3 |
| | | buildTarget: DefaultTexturePlatform |
| | | maxTextureSize: 2048 |
| | | resizeAlgorithm: 0 |
| | | textureFormat: -1 |
| | | textureCompression: 1 |
| | | compressionQuality: 50 |
| | | crunchedCompression: 0 |
| | | allowsAlphaSplitting: 0 |
| | | overridden: 0 |
| | | androidETC2FallbackOverride: 0 |
| | | forceMaximumCompressionQuality_BC6H_BC7: 0 |
| | | spriteSheet: |
| | | serializedVersion: 2 |
| | | sprites: [] |
| | | outline: [] |
| | | physicsShape: [] |
| | | bones: [] |
| | | spriteID: 5e97eb03825dee720800000000000000 |
| | | internalID: 0 |
| | | vertices: [] |
| | | indices: |
| | | edges: [] |
| | | weights: [] |
| | | secondaryTextures: [] |
| | | spritePackingTag: |
| | | pSDRemoveMatte: 0 |
| | | pSDShowRemoveMatteOption: 0 |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 074989d7b86364a53a55747e7ba89881 |
| | | TextureImporter: |
| | | internalIDToNameTable: [] |
| | | externalObjects: {} |
| | | serializedVersion: 11 |
| | | mipmaps: |
| | | mipMapMode: 0 |
| | | enableMipMap: 0 |
| | | sRGBTexture: 1 |
| | | linearTexture: 0 |
| | | fadeOut: 0 |
| | | borderMipMap: 0 |
| | | mipMapsPreserveCoverage: 0 |
| | | alphaTestReferenceValue: 0.5 |
| | | mipMapFadeDistanceStart: 1 |
| | | mipMapFadeDistanceEnd: 3 |
| | | bumpmap: |
| | | convertToNormalMap: 0 |
| | | externalNormalMap: 0 |
| | | heightScale: 0.25 |
| | | normalMapFilter: 0 |
| | | isReadable: 0 |
| | | streamingMipmaps: 0 |
| | | streamingMipmapsPriority: 0 |
| | | grayScaleToAlpha: 0 |
| | | generateCubemap: 6 |
| | | cubemapConvolution: 0 |
| | | seamlessCubemap: 0 |
| | | textureFormat: -1 |
| | | maxTextureSize: 2048 |
| | | textureSettings: |
| | | serializedVersion: 2 |
| | | filterMode: -1 |
| | | aniso: -1 |
| | | mipBias: -100 |
| | | wrapU: 1 |
| | | wrapV: 1 |
| | | wrapW: 1 |
| | | nPOTScale: 0 |
| | | lightmap: 0 |
| | | compressionQuality: 50 |
| | | spriteMode: 1 |
| | | spriteExtrude: 1 |
| | | spriteMeshType: 1 |
| | | alignment: 0 |
| | | spritePivot: {x: 0.5, y: 0.5} |
| | | spritePixelsToUnits: 100 |
| | | spriteBorder: {x: 0, y: 0, z: 0, w: 0} |
| | | spriteGenerateFallbackPhysicsShape: 1 |
| | | alphaUsage: 1 |
| | | alphaIsTransparency: 1 |
| | | spriteTessellationDetail: -1 |
| | | textureType: 8 |
| | | textureShape: 1 |
| | | singleChannelComponent: 0 |
| | | maxTextureSizeSet: 0 |
| | | compressionQualitySet: 0 |
| | | textureFormatSet: 0 |
| | | applyGammaDecoding: 1 |
| | | platformSettings: |
| | | - serializedVersion: 3 |
| | | buildTarget: DefaultTexturePlatform |
| | | maxTextureSize: 2048 |
| | | resizeAlgorithm: 0 |
| | | textureFormat: -1 |
| | | textureCompression: 1 |
| | | compressionQuality: 50 |
| | | crunchedCompression: 0 |
| | | allowsAlphaSplitting: 0 |
| | | overridden: 0 |
| | | androidETC2FallbackOverride: 0 |
| | | forceMaximumCompressionQuality_BC6H_BC7: 0 |
| | | spriteSheet: |
| | | serializedVersion: 2 |
| | | sprites: [] |
| | | outline: [] |
| | | physicsShape: [] |
| | | bones: [] |
| | | spriteID: 5e97eb03825dee720800000000000000 |
| | | internalID: 0 |
| | | vertices: [] |
| | | indices: |
| | | edges: [] |
| | | weights: [] |
| | | secondaryTextures: [] |
| | | spritePackingTag: |
| | | pSDRemoveMatte: 0 |
| | | pSDShowRemoveMatteOption: 0 |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: deb9343e59089a44298909844f6774d6 |
| | | TextureImporter: |
| | | internalIDToNameTable: [] |
| | | externalObjects: {} |
| | | serializedVersion: 11 |
| | | mipmaps: |
| | | mipMapMode: 0 |
| | | enableMipMap: 0 |
| | | sRGBTexture: 1 |
| | | linearTexture: 0 |
| | | fadeOut: 0 |
| | | borderMipMap: 0 |
| | | mipMapsPreserveCoverage: 0 |
| | | alphaTestReferenceValue: 0.5 |
| | | mipMapFadeDistanceStart: 1 |
| | | mipMapFadeDistanceEnd: 3 |
| | | bumpmap: |
| | | convertToNormalMap: 0 |
| | | externalNormalMap: 0 |
| | | heightScale: 0.25 |
| | | normalMapFilter: 0 |
| | | isReadable: 0 |
| | | streamingMipmaps: 0 |
| | | streamingMipmapsPriority: 0 |
| | | grayScaleToAlpha: 0 |
| | | generateCubemap: 6 |
| | | cubemapConvolution: 0 |
| | | seamlessCubemap: 0 |
| | | textureFormat: -2 |
| | | maxTextureSize: 2048 |
| | | textureSettings: |
| | | serializedVersion: 2 |
| | | filterMode: -1 |
| | | aniso: -1 |
| | | mipBias: -100 |
| | | wrapU: 1 |
| | | wrapV: 1 |
| | | wrapW: 1 |
| | | nPOTScale: 0 |
| | | lightmap: 0 |
| | | compressionQuality: 50 |
| | | spriteMode: 1 |
| | | spriteExtrude: 1 |
| | | spriteMeshType: 1 |
| | | alignment: 0 |
| | | spritePivot: {x: 0.5, y: 0.5} |
| | | spritePixelsToUnits: 100 |
| | | spriteBorder: {x: 0, y: 0, z: 0, w: 0} |
| | | spriteGenerateFallbackPhysicsShape: 1 |
| | | alphaUsage: 1 |
| | | alphaIsTransparency: 1 |
| | | spriteTessellationDetail: -1 |
| | | textureType: 8 |
| | | textureShape: 1 |
| | | singleChannelComponent: 0 |
| | | maxTextureSizeSet: 0 |
| | | compressionQualitySet: 0 |
| | | textureFormatSet: 0 |
| | | applyGammaDecoding: 1 |
| | | platformSettings: |
| | | - serializedVersion: 3 |
| | | buildTarget: DefaultTexturePlatform |
| | | maxTextureSize: 2048 |
| | | resizeAlgorithm: 0 |
| | | textureFormat: -1 |
| | | textureCompression: 1 |
| | | compressionQuality: 50 |
| | | crunchedCompression: 0 |
| | | allowsAlphaSplitting: 0 |
| | | overridden: 0 |
| | | androidETC2FallbackOverride: 0 |
| | | forceMaximumCompressionQuality_BC6H_BC7: 0 |
| | | spriteSheet: |
| | | serializedVersion: 2 |
| | | sprites: [] |
| | | outline: [] |
| | | physicsShape: [] |
| | | bones: [] |
| | | spriteID: 5e97eb03825dee720800000000000000 |
| | | internalID: 0 |
| | | vertices: [] |
| | | indices: |
| | | edges: [] |
| | | weights: [] |
| | | secondaryTextures: [] |
| | | spritePackingTag: |
| | | pSDRemoveMatte: 0 |
| | | pSDShowRemoveMatteOption: 0 |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 7e5b508f0e7a3402cb449b8efc90b8b3 |
| | | TextureImporter: |
| | | internalIDToNameTable: [] |
| | | externalObjects: {} |
| | | serializedVersion: 11 |
| | | mipmaps: |
| | | mipMapMode: 0 |
| | | enableMipMap: 0 |
| | | sRGBTexture: 1 |
| | | linearTexture: 0 |
| | | fadeOut: 0 |
| | | borderMipMap: 0 |
| | | mipMapsPreserveCoverage: 0 |
| | | alphaTestReferenceValue: 0.5 |
| | | mipMapFadeDistanceStart: 1 |
| | | mipMapFadeDistanceEnd: 3 |
| | | bumpmap: |
| | | convertToNormalMap: 0 |
| | | externalNormalMap: 0 |
| | | heightScale: 0.25 |
| | | normalMapFilter: 0 |
| | | isReadable: 0 |
| | | streamingMipmaps: 0 |
| | | streamingMipmapsPriority: 0 |
| | | grayScaleToAlpha: 0 |
| | | generateCubemap: 6 |
| | | cubemapConvolution: 0 |
| | | seamlessCubemap: 0 |
| | | textureFormat: -1 |
| | | maxTextureSize: 2048 |
| | | textureSettings: |
| | | serializedVersion: 2 |
| | | filterMode: -1 |
| | | aniso: -1 |
| | | mipBias: -100 |
| | | wrapU: 1 |
| | | wrapV: 1 |
| | | wrapW: 1 |
| | | nPOTScale: 0 |
| | | lightmap: 0 |
| | | compressionQuality: 50 |
| | | spriteMode: 1 |
| | | spriteExtrude: 1 |
| | | spriteMeshType: 1 |
| | | alignment: 0 |
| | | spritePivot: {x: 0.5, y: 0.5} |
| | | spritePixelsToUnits: 100 |
| | | spriteBorder: {x: 0, y: 0, z: 0, w: 0} |
| | | spriteGenerateFallbackPhysicsShape: 1 |
| | | alphaUsage: 1 |
| | | alphaIsTransparency: 1 |
| | | spriteTessellationDetail: -1 |
| | | textureType: 8 |
| | | textureShape: 1 |
| | | singleChannelComponent: 0 |
| | | maxTextureSizeSet: 0 |
| | | compressionQualitySet: 0 |
| | | textureFormatSet: 0 |
| | | applyGammaDecoding: 1 |
| | | platformSettings: |
| | | - serializedVersion: 3 |
| | | buildTarget: DefaultTexturePlatform |
| | | maxTextureSize: 2048 |
| | | resizeAlgorithm: 0 |
| | | textureFormat: -1 |
| | | textureCompression: 1 |
| | | compressionQuality: 50 |
| | | crunchedCompression: 0 |
| | | allowsAlphaSplitting: 0 |
| | | overridden: 0 |
| | | androidETC2FallbackOverride: 0 |
| | | forceMaximumCompressionQuality_BC6H_BC7: 0 |
| | | spriteSheet: |
| | | serializedVersion: 2 |
| | | sprites: [] |
| | | outline: [] |
| | | physicsShape: [] |
| | | bones: [] |
| | | spriteID: 5e97eb03825dee720800000000000000 |
| | | internalID: 0 |
| | | vertices: [] |
| | | indices: |
| | | edges: [] |
| | | weights: [] |
| | | secondaryTextures: [] |
| | | spritePackingTag: |
| | | pSDRemoveMatte: 0 |
| | | pSDShowRemoveMatteOption: 0 |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: f6f48c4c35c3947f98b2e8172e9711a1 |
| | | TextureImporter: |
| | | internalIDToNameTable: [] |
| | | externalObjects: {} |
| | | serializedVersion: 11 |
| | | mipmaps: |
| | | mipMapMode: 0 |
| | | enableMipMap: 0 |
| | | sRGBTexture: 1 |
| | | linearTexture: 0 |
| | | fadeOut: 0 |
| | | borderMipMap: 0 |
| | | mipMapsPreserveCoverage: 0 |
| | | alphaTestReferenceValue: 0.5 |
| | | mipMapFadeDistanceStart: 1 |
| | | mipMapFadeDistanceEnd: 3 |
| | | bumpmap: |
| | | convertToNormalMap: 0 |
| | | externalNormalMap: 0 |
| | | heightScale: 0.25 |
| | | normalMapFilter: 0 |
| | | isReadable: 0 |
| | | streamingMipmaps: 0 |
| | | streamingMipmapsPriority: 0 |
| | | grayScaleToAlpha: 0 |
| | | generateCubemap: 6 |
| | | cubemapConvolution: 0 |
| | | seamlessCubemap: 0 |
| | | textureFormat: -1 |
| | | maxTextureSize: 2048 |
| | | textureSettings: |
| | | serializedVersion: 2 |
| | | filterMode: -1 |
| | | aniso: -1 |
| | | mipBias: -100 |
| | | wrapU: 1 |
| | | wrapV: 1 |
| | | wrapW: 1 |
| | | nPOTScale: 0 |
| | | lightmap: 0 |
| | | compressionQuality: 50 |
| | | spriteMode: 1 |
| | | spriteExtrude: 1 |
| | | spriteMeshType: 1 |
| | | alignment: 0 |
| | | spritePivot: {x: 0.5, y: 0.5} |
| | | spritePixelsToUnits: 100 |
| | | spriteBorder: {x: 0, y: 0, z: 0, w: 0} |
| | | spriteGenerateFallbackPhysicsShape: 1 |
| | | alphaUsage: 1 |
| | | alphaIsTransparency: 1 |
| | | spriteTessellationDetail: -1 |
| | | textureType: 8 |
| | | textureShape: 1 |
| | | singleChannelComponent: 0 |
| | | maxTextureSizeSet: 0 |
| | | compressionQualitySet: 0 |
| | | textureFormatSet: 0 |
| | | applyGammaDecoding: 1 |
| | | platformSettings: |
| | | - serializedVersion: 3 |
| | | buildTarget: DefaultTexturePlatform |
| | | maxTextureSize: 2048 |
| | | resizeAlgorithm: 0 |
| | | textureFormat: -1 |
| | | textureCompression: 1 |
| | | compressionQuality: 50 |
| | | crunchedCompression: 0 |
| | | allowsAlphaSplitting: 0 |
| | | overridden: 0 |
| | | androidETC2FallbackOverride: 0 |
| | | forceMaximumCompressionQuality_BC6H_BC7: 0 |
| | | spriteSheet: |
| | | serializedVersion: 2 |
| | | sprites: [] |
| | | outline: [] |
| | | physicsShape: [] |
| | | bones: [] |
| | | spriteID: 5e97eb03825dee720800000000000000 |
| | | internalID: 0 |
| | | vertices: [] |
| | | indices: |
| | | edges: [] |
| | | weights: [] |
| | | secondaryTextures: [] |
| | | spritePackingTag: |
| | | pSDRemoveMatte: 0 |
| | | pSDShowRemoveMatteOption: 0 |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 94ec5313dd85b487987379ce18be44f5 |
| | | TextureImporter: |
| | | internalIDToNameTable: [] |
| | | externalObjects: {} |
| | | serializedVersion: 11 |
| | | mipmaps: |
| | | mipMapMode: 0 |
| | | enableMipMap: 0 |
| | | sRGBTexture: 1 |
| | | linearTexture: 0 |
| | | fadeOut: 0 |
| | | borderMipMap: 0 |
| | | mipMapsPreserveCoverage: 0 |
| | | alphaTestReferenceValue: 0.5 |
| | | mipMapFadeDistanceStart: 1 |
| | | mipMapFadeDistanceEnd: 3 |
| | | bumpmap: |
| | | convertToNormalMap: 0 |
| | | externalNormalMap: 0 |
| | | heightScale: 0.25 |
| | | normalMapFilter: 0 |
| | | isReadable: 0 |
| | | streamingMipmaps: 0 |
| | | streamingMipmapsPriority: 0 |
| | | grayScaleToAlpha: 0 |
| | | generateCubemap: 6 |
| | | cubemapConvolution: 0 |
| | | seamlessCubemap: 0 |
| | | textureFormat: -1 |
| | | maxTextureSize: 2048 |
| | | textureSettings: |
| | | serializedVersion: 2 |
| | | filterMode: 1 |
| | | aniso: -1 |
| | | mipBias: -100 |
| | | wrapU: 1 |
| | | wrapV: 1 |
| | | wrapW: 1 |
| | | nPOTScale: 0 |
| | | lightmap: 0 |
| | | compressionQuality: 50 |
| | | spriteMode: 1 |
| | | spriteExtrude: 1 |
| | | spriteMeshType: 1 |
| | | alignment: 0 |
| | | spritePivot: {x: 0.5, y: 0.5} |
| | | spritePixelsToUnits: 100 |
| | | spriteBorder: {x: 0, y: 0, z: 0, w: 0} |
| | | spriteGenerateFallbackPhysicsShape: 1 |
| | | alphaUsage: 1 |
| | | alphaIsTransparency: 1 |
| | | spriteTessellationDetail: -1 |
| | | textureType: 8 |
| | | textureShape: 1 |
| | | singleChannelComponent: 0 |
| | | maxTextureSizeSet: 0 |
| | | compressionQualitySet: 0 |
| | | textureFormatSet: 0 |
| | | applyGammaDecoding: 1 |
| | | platformSettings: |
| | | - serializedVersion: 3 |
| | | buildTarget: DefaultTexturePlatform |
| | | maxTextureSize: 2048 |
| | | resizeAlgorithm: 0 |
| | | textureFormat: -1 |
| | | textureCompression: 1 |
| | | compressionQuality: 50 |
| | | crunchedCompression: 0 |
| | | allowsAlphaSplitting: 0 |
| | | overridden: 0 |
| | | androidETC2FallbackOverride: 0 |
| | | forceMaximumCompressionQuality_BC6H_BC7: 0 |
| | | spriteSheet: |
| | | serializedVersion: 2 |
| | | sprites: [] |
| | | outline: [] |
| | | physicsShape: [] |
| | | bones: [] |
| | | spriteID: 5e97eb03825dee720800000000000000 |
| | | internalID: 0 |
| | | vertices: [] |
| | | indices: |
| | | edges: [] |
| | | weights: [] |
| | | secondaryTextures: [] |
| | | spritePackingTag: |
| | | pSDRemoveMatte: 0 |
| | | pSDShowRemoveMatteOption: 0 |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 5a4ab2e5e00054b03a7bf96d03e5b4e1 |
| | | guid: 9baa019b99e186744b49375f37111e90 |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | /* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited |
| | | Written by Jean-Marc Valin and Koen Vos */ |
| | | /* |
| | | 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. |
| | | |
| | | 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. |
| | | */ |
| | | |
| | | /** |
| | | * @file opus.h |
| | | * @brief Opus reference implementation API |
| | | */ |
| | | |
| | | #ifndef OPUS_H |
| | | #define OPUS_H |
| | | |
| | | #include "opus_types.h" |
| | | #include "opus_defines.h" |
| | | |
| | | #ifdef __cplusplus |
| | | extern "C" { |
| | | #endif |
| | | |
| | | /** |
| | | * @mainpage Opus |
| | | * |
| | | * The Opus codec is designed for interactive speech and audio transmission over the Internet. |
| | | * It is designed by the IETF Codec Working Group and incorporates technology from |
| | | * Skype's SILK codec and Xiph.Org's CELT codec. |
| | | * |
| | | * The Opus codec is designed to handle a wide range of interactive audio applications, |
| | | * including Voice over IP, videoconferencing, in-game chat, and even remote live music |
| | | * performances. It can scale from low bit-rate narrowband speech to very high quality |
| | | * stereo music. Its main features are: |
| | | |
| | | * @li Sampling rates from 8 to 48 kHz |
| | | * @li Bit-rates from 6 kb/s to 510 kb/s |
| | | * @li Support for both constant bit-rate (CBR) and variable bit-rate (VBR) |
| | | * @li Audio bandwidth from narrowband to full-band |
| | | * @li Support for speech and music |
| | | * @li Support for mono and stereo |
| | | * @li Support for multichannel (up to 255 channels) |
| | | * @li Frame sizes from 2.5 ms to 60 ms |
| | | * @li Good loss robustness and packet loss concealment (PLC) |
| | | * @li Floating point and fixed-point implementation |
| | | * |
| | | * Documentation sections: |
| | | * @li @ref opus_encoder |
| | | * @li @ref opus_decoder |
| | | * @li @ref opus_repacketizer |
| | | * @li @ref opus_multistream |
| | | * @li @ref opus_libinfo |
| | | * @li @ref opus_custom |
| | | */ |
| | | |
| | | /** @defgroup opus_encoder Opus Encoder |
| | | * @{ |
| | | * |
| | | * @brief This page describes the process and functions used to encode Opus. |
| | | * |
| | | * Since Opus is a stateful codec, the encoding process starts with creating an encoder |
| | | * state. This can be done with: |
| | | * |
| | | * @code |
| | | * int error; |
| | | * OpusEncoder *enc; |
| | | * enc = opus_encoder_create(Fs, channels, application, &error); |
| | | * @endcode |
| | | * |
| | | * From this point, @c enc can be used for encoding an audio stream. An encoder state |
| | | * @b must @b not be used for more than one stream at the same time. Similarly, the encoder |
| | | * state @b must @b not be re-initialized for each frame. |
| | | * |
| | | * While opus_encoder_create() allocates memory for the state, it's also possible |
| | | * to initialize pre-allocated memory: |
| | | * |
| | | * @code |
| | | * int size; |
| | | * int error; |
| | | * OpusEncoder *enc; |
| | | * size = opus_encoder_get_size(channels); |
| | | * enc = malloc(size); |
| | | * error = opus_encoder_init(enc, Fs, channels, application); |
| | | * @endcode |
| | | * |
| | | * where opus_encoder_get_size() returns the required size for the encoder state. Note that |
| | | * future versions of this code may change the size, so no assuptions should be made about it. |
| | | * |
| | | * The encoder state is always continuous in memory and only a shallow copy is sufficient |
| | | * to copy it (e.g. memcpy()) |
| | | * |
| | | * It is possible to change some of the encoder's settings using the opus_encoder_ctl() |
| | | * interface. All these settings already default to the recommended value, so they should |
| | | * only be changed when necessary. The most common settings one may want to change are: |
| | | * |
| | | * @code |
| | | * opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate)); |
| | | * opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity)); |
| | | * opus_encoder_ctl(enc, OPUS_SET_SIGNAL(signal_type)); |
| | | * @endcode |
| | | * |
| | | * where |
| | | * |
| | | * @arg bitrate is in bits per second (b/s) |
| | | * @arg complexity is a value from 1 to 10, where 1 is the lowest complexity and 10 is the highest |
| | | * @arg signal_type is either OPUS_AUTO (default), OPUS_SIGNAL_VOICE, or OPUS_SIGNAL_MUSIC |
| | | * |
| | | * See @ref opus_encoderctls and @ref opus_genericctls for a complete list of parameters that can be set or queried. Most parameters can be set or changed at any time during a stream. |
| | | * |
| | | * To encode a frame, opus_encode() or opus_encode_float() must be called with exactly one frame (2.5, 5, 10, 20, 40 or 60 ms) of audio data: |
| | | * @code |
| | | * len = opus_encode(enc, audio_frame, frame_size, packet, max_packet); |
| | | * @endcode |
| | | * |
| | | * where |
| | | * <ul> |
| | | * <li>audio_frame is the audio data in opus_int16 (or float for opus_encode_float())</li> |
| | | * <li>frame_size is the duration of the frame in samples (per channel)</li> |
| | | * <li>packet is the byte array to which the compressed data is written</li> |
| | | * <li>max_packet is the maximum number of bytes that can be written in the packet (4000 bytes is recommended). |
| | | * Do not use max_packet to control VBR target bitrate, instead use the #OPUS_SET_BITRATE CTL.</li> |
| | | * </ul> |
| | | * |
| | | * opus_encode() and opus_encode_float() return the number of bytes actually written to the packet. |
| | | * The return value <b>can be negative</b>, which indicates that an error has occurred. If the return value |
| | | * is 2 bytes or less, then the packet does not need to be transmitted (DTX). |
| | | * |
| | | * Once the encoder state if no longer needed, it can be destroyed with |
| | | * |
| | | * @code |
| | | * opus_encoder_destroy(enc); |
| | | * @endcode |
| | | * |
| | | * If the encoder was created with opus_encoder_init() rather than opus_encoder_create(), |
| | | * then no action is required aside from potentially freeing the memory that was manually |
| | | * allocated for it (calling free(enc) for the example above) |
| | | * |
| | | */ |
| | | |
| | | /** Opus encoder state. |
| | | * This contains the complete state of an Opus encoder. |
| | | * It is position independent and can be freely copied. |
| | | * @see opus_encoder_create,opus_encoder_init |
| | | */ |
| | | typedef struct OpusEncoder OpusEncoder; |
| | | |
| | | /** Gets the size of an <code>OpusEncoder</code> structure. |
| | | * @param[in] channels <tt>int</tt>: Number of channels. |
| | | * This must be 1 or 2. |
| | | * @returns The size in bytes. |
| | | */ |
| | | OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_encoder_get_size(int channels); |
| | | |
| | | /** |
| | | */ |
| | | |
| | | /** Allocates and initializes an encoder state. |
| | | * There are three coding modes: |
| | | * |
| | | * @ref OPUS_APPLICATION_VOIP gives best quality at a given bitrate for voice |
| | | * signals. It enhances the input signal by high-pass filtering and |
| | | * emphasizing formants and harmonics. Optionally it includes in-band |
| | | * forward error correction to protect against packet loss. Use this |
| | | * mode for typical VoIP applications. Because of the enhancement, |
| | | * even at high bitrates the output may sound different from the input. |
| | | * |
| | | * @ref OPUS_APPLICATION_AUDIO gives best quality at a given bitrate for most |
| | | * non-voice signals like music. Use this mode for music and mixed |
| | | * (music/voice) content, broadcast, and applications requiring less |
| | | * than 15 ms of coding delay. |
| | | * |
| | | * @ref OPUS_APPLICATION_RESTRICTED_LOWDELAY configures low-delay mode that |
| | | * disables the speech-optimized mode in exchange for slightly reduced delay. |
| | | * This mode can only be set on an newly initialized or freshly reset encoder |
| | | * because it changes the codec delay. |
| | | * |
| | | * This is useful when the caller knows that the speech-optimized modes will not be needed (use with caution). |
| | | * @param [in] Fs <tt>opus_int32</tt>: Sampling rate of input signal (Hz) |
| | | * This must be one of 8000, 12000, 16000, |
| | | * 24000, or 48000. |
| | | * @param [in] channels <tt>int</tt>: Number of channels (1 or 2) in input signal |
| | | * @param [in] application <tt>int</tt>: Coding mode (@ref OPUS_APPLICATION_VOIP/@ref OPUS_APPLICATION_AUDIO/@ref OPUS_APPLICATION_RESTRICTED_LOWDELAY) |
| | | * @param [out] error <tt>int*</tt>: @ref opus_errorcodes |
| | | * @note Regardless of the sampling rate and number channels selected, the Opus encoder |
| | | * can switch to a lower audio bandwidth or number of channels if the bitrate |
| | | * selected is too low. This also means that it is safe to always use 48 kHz stereo input |
| | | * and let the encoder optimize the encoding. |
| | | */ |
| | | OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusEncoder *opus_encoder_create( |
| | | opus_int32 Fs, |
| | | int channels, |
| | | int application, |
| | | int *error |
| | | ); |
| | | |
| | | /** Initializes a previously allocated encoder state |
| | | * The memory pointed to by st must be at least the size returned by opus_encoder_get_size(). |
| | | * This is intended for applications which use their own allocator instead of malloc. |
| | | * @see opus_encoder_create(),opus_encoder_get_size() |
| | | * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. |
| | | * @param [in] st <tt>OpusEncoder*</tt>: Encoder state |
| | | * @param [in] Fs <tt>opus_int32</tt>: Sampling rate of input signal (Hz) |
| | | * This must be one of 8000, 12000, 16000, |
| | | * 24000, or 48000. |
| | | * @param [in] channels <tt>int</tt>: Number of channels (1 or 2) in input signal |
| | | * @param [in] application <tt>int</tt>: Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO/OPUS_APPLICATION_RESTRICTED_LOWDELAY) |
| | | * @retval #OPUS_OK Success or @ref opus_errorcodes |
| | | */ |
| | | OPUS_EXPORT int opus_encoder_init( |
| | | OpusEncoder *st, |
| | | opus_int32 Fs, |
| | | int channels, |
| | | int application |
| | | ) OPUS_ARG_NONNULL(1); |
| | | |
| | | /** Encodes an Opus frame. |
| | | * @param [in] st <tt>OpusEncoder*</tt>: Encoder state |
| | | * @param [in] pcm <tt>opus_int16*</tt>: Input signal (interleaved if 2 channels). length is frame_size*channels*sizeof(opus_int16) |
| | | * @param [in] frame_size <tt>int</tt>: Number of samples per channel in the |
| | | * input signal. |
| | | * This must be an Opus frame size for |
| | | * the encoder's sampling rate. |
| | | * For example, at 48 kHz the permitted |
| | | * values are 120, 240, 480, 960, 1920, |
| | | * and 2880. |
| | | * Passing in a duration of less than |
| | | * 10 ms (480 samples at 48 kHz) will |
| | | * prevent the encoder from using the LPC |
| | | * or hybrid modes. |
| | | * @param [out] data <tt>unsigned char*</tt>: Output payload. |
| | | * This must contain storage for at |
| | | * least \a max_data_bytes. |
| | | * @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated |
| | | * memory for the output |
| | | * payload. This may be |
| | | * used to impose an upper limit on |
| | | * the instant bitrate, but should |
| | | * not be used as the only bitrate |
| | | * control. Use #OPUS_SET_BITRATE to |
| | | * control the bitrate. |
| | | * @returns The length of the encoded packet (in bytes) on success or a |
| | | * negative error code (see @ref opus_errorcodes) on failure. |
| | | */ |
| | | OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode( |
| | | OpusEncoder *st, |
| | | const opus_int16 *pcm, |
| | | int frame_size, |
| | | unsigned char *data, |
| | | opus_int32 max_data_bytes |
| | | ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); |
| | | |
| | | /** Encodes an Opus frame from floating point input. |
| | | * @param [in] st <tt>OpusEncoder*</tt>: Encoder state |
| | | * @param [in] pcm <tt>float*</tt>: Input in float format (interleaved if 2 channels), with a normal range of +/-1.0. |
| | | * Samples with a range beyond +/-1.0 are supported but will |
| | | * be clipped by decoders using the integer API and should |
| | | * only be used if it is known that the far end supports |
| | | * extended dynamic range. |
| | | * length is frame_size*channels*sizeof(float) |
| | | * @param [in] frame_size <tt>int</tt>: Number of samples per channel in the |
| | | * input signal. |
| | | * This must be an Opus frame size for |
| | | * the encoder's sampling rate. |
| | | * For example, at 48 kHz the permitted |
| | | * values are 120, 240, 480, 960, 1920, |
| | | * and 2880. |
| | | * Passing in a duration of less than |
| | | * 10 ms (480 samples at 48 kHz) will |
| | | * prevent the encoder from using the LPC |
| | | * or hybrid modes. |
| | | * @param [out] data <tt>unsigned char*</tt>: Output payload. |
| | | * This must contain storage for at |
| | | * least \a max_data_bytes. |
| | | * @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated |
| | | * memory for the output |
| | | * payload. This may be |
| | | * used to impose an upper limit on |
| | | * the instant bitrate, but should |
| | | * not be used as the only bitrate |
| | | * control. Use #OPUS_SET_BITRATE to |
| | | * control the bitrate. |
| | | * @returns The length of the encoded packet (in bytes) on success or a |
| | | * negative error code (see @ref opus_errorcodes) on failure. |
| | | */ |
| | | OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode_float( |
| | | OpusEncoder *st, |
| | | const float *pcm, |
| | | int frame_size, |
| | | unsigned char *data, |
| | | opus_int32 max_data_bytes |
| | | ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); |
| | | |
| | | /** Frees an <code>OpusEncoder</code> allocated by opus_encoder_create(). |
| | | * @param[in] st <tt>OpusEncoder*</tt>: State to be freed. |
| | | */ |
| | | OPUS_EXPORT void opus_encoder_destroy(OpusEncoder *st); |
| | | |
| | | /** Perform a CTL function on an Opus encoder. |
| | | * |
| | | * Generally the request and subsequent arguments are generated |
| | | * by a convenience macro. |
| | | * @param st <tt>OpusEncoder*</tt>: Encoder state. |
| | | * @param request This and all remaining parameters should be replaced by one |
| | | * of the convenience macros in @ref opus_genericctls or |
| | | * @ref opus_encoderctls. |
| | | * @see opus_genericctls |
| | | * @see opus_encoderctls |
| | | */ |
| | | OPUS_EXPORT int opus_encoder_ctl(OpusEncoder *st, int request, ...) OPUS_ARG_NONNULL(1); |
| | | /**@}*/ |
| | | |
| | | /** @defgroup opus_decoder Opus Decoder |
| | | * @{ |
| | | * |
| | | * @brief This page describes the process and functions used to decode Opus. |
| | | * |
| | | * The decoding process also starts with creating a decoder |
| | | * state. This can be done with: |
| | | * @code |
| | | * int error; |
| | | * OpusDecoder *dec; |
| | | * dec = opus_decoder_create(Fs, channels, &error); |
| | | * @endcode |
| | | * where |
| | | * @li Fs is the sampling rate and must be 8000, 12000, 16000, 24000, or 48000 |
| | | * @li channels is the number of channels (1 or 2) |
| | | * @li error will hold the error code in case of failure (or #OPUS_OK on success) |
| | | * @li the return value is a newly created decoder state to be used for decoding |
| | | * |
| | | * While opus_decoder_create() allocates memory for the state, it's also possible |
| | | * to initialize pre-allocated memory: |
| | | * @code |
| | | * int size; |
| | | * int error; |
| | | * OpusDecoder *dec; |
| | | * size = opus_decoder_get_size(channels); |
| | | * dec = malloc(size); |
| | | * error = opus_decoder_init(dec, Fs, channels); |
| | | * @endcode |
| | | * where opus_decoder_get_size() returns the required size for the decoder state. Note that |
| | | * future versions of this code may change the size, so no assuptions should be made about it. |
| | | * |
| | | * The decoder state is always continuous in memory and only a shallow copy is sufficient |
| | | * to copy it (e.g. memcpy()) |
| | | * |
| | | * To decode a frame, opus_decode() or opus_decode_float() must be called with a packet of compressed audio data: |
| | | * @code |
| | | * frame_size = opus_decode(dec, packet, len, decoded, max_size, 0); |
| | | * @endcode |
| | | * where |
| | | * |
| | | * @li packet is the byte array containing the compressed data |
| | | * @li len is the exact number of bytes contained in the packet |
| | | * @li decoded is the decoded audio data in opus_int16 (or float for opus_decode_float()) |
| | | * @li max_size is the max duration of the frame in samples (per channel) that can fit into the decoded_frame array |
| | | * |
| | | * opus_decode() and opus_decode_float() return the number of samples (per channel) decoded from the packet. |
| | | * If that value is negative, then an error has occurred. This can occur if the packet is corrupted or if the audio |
| | | * buffer is too small to hold the decoded audio. |
| | | * |
| | | * Opus is a stateful codec with overlapping blocks and as a result Opus |
| | | * packets are not coded independently of each other. Packets must be |
| | | * passed into the decoder serially and in the correct order for a correct |
| | | * decode. Lost packets can be replaced with loss concealment by calling |
| | | * the decoder with a null pointer and zero length for the missing packet. |
| | | * |
| | | * A single codec state may only be accessed from a single thread at |
| | | * a time and any required locking must be performed by the caller. Separate |
| | | * streams must be decoded with separate decoder states and can be decoded |
| | | * in parallel unless the library was compiled with NONTHREADSAFE_PSEUDOSTACK |
| | | * defined. |
| | | * |
| | | */ |
| | | |
| | | /** Opus decoder state. |
| | | * This contains the complete state of an Opus decoder. |
| | | * It is position independent and can be freely copied. |
| | | * @see opus_decoder_create,opus_decoder_init |
| | | */ |
| | | typedef struct OpusDecoder OpusDecoder; |
| | | |
| | | /** Gets the size of an <code>OpusDecoder</code> structure. |
| | | * @param [in] channels <tt>int</tt>: Number of channels. |
| | | * This must be 1 or 2. |
| | | * @returns The size in bytes. |
| | | */ |
| | | OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decoder_get_size(int channels); |
| | | |
| | | /** Allocates and initializes a decoder state. |
| | | * @param [in] Fs <tt>opus_int32</tt>: Sample rate to decode at (Hz). |
| | | * This must be one of 8000, 12000, 16000, |
| | | * 24000, or 48000. |
| | | * @param [in] channels <tt>int</tt>: Number of channels (1 or 2) to decode |
| | | * @param [out] error <tt>int*</tt>: #OPUS_OK Success or @ref opus_errorcodes |
| | | * |
| | | * Internally Opus stores data at 48000 Hz, so that should be the default |
| | | * value for Fs. However, the decoder can efficiently decode to buffers |
| | | * at 8, 12, 16, and 24 kHz so if for some reason the caller cannot use |
| | | * data at the full sample rate, or knows the compressed data doesn't |
| | | * use the full frequency range, it can request decoding at a reduced |
| | | * rate. Likewise, the decoder is capable of filling in either mono or |
| | | * interleaved stereo pcm buffers, at the caller's request. |
| | | */ |
| | | OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusDecoder *opus_decoder_create( |
| | | opus_int32 Fs, |
| | | int channels, |
| | | int *error |
| | | ); |
| | | |
| | | /** Initializes a previously allocated decoder state. |
| | | * The state must be at least the size returned by opus_decoder_get_size(). |
| | | * This is intended for applications which use their own allocator instead of malloc. @see opus_decoder_create,opus_decoder_get_size |
| | | * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. |
| | | * @param [in] st <tt>OpusDecoder*</tt>: Decoder state. |
| | | * @param [in] Fs <tt>opus_int32</tt>: Sampling rate to decode to (Hz). |
| | | * This must be one of 8000, 12000, 16000, |
| | | * 24000, or 48000. |
| | | * @param [in] channels <tt>int</tt>: Number of channels (1 or 2) to decode |
| | | * @retval #OPUS_OK Success or @ref opus_errorcodes |
| | | */ |
| | | OPUS_EXPORT int opus_decoder_init( |
| | | OpusDecoder *st, |
| | | opus_int32 Fs, |
| | | int channels |
| | | ) OPUS_ARG_NONNULL(1); |
| | | |
| | | /** Decode an Opus packet. |
| | | * @param [in] st <tt>OpusDecoder*</tt>: Decoder state |
| | | * @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss |
| | | * @param [in] len <tt>opus_int32</tt>: Number of bytes in payload* |
| | | * @param [out] pcm <tt>opus_int16*</tt>: Output signal (interleaved if 2 channels). length |
| | | * is frame_size*channels*sizeof(opus_int16) |
| | | * @param [in] frame_size Number of samples per channel of available space in \a pcm. |
| | | * If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will |
| | | * not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1), |
| | | * then frame_size needs to be exactly the duration of audio that is missing, otherwise the |
| | | * decoder will not be in the optimal state to decode the next incoming packet. For the PLC and |
| | | * FEC cases, frame_size <b>must</b> be a multiple of 2.5 ms. |
| | | * @param [in] decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band forward error correction data be |
| | | * decoded. If no such data is available, the frame is decoded as if it were lost. |
| | | * @returns Number of decoded samples or @ref opus_errorcodes |
| | | */ |
| | | OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode( |
| | | OpusDecoder *st, |
| | | const unsigned char *data, |
| | | opus_int32 len, |
| | | opus_int16 *pcm, |
| | | int frame_size, |
| | | int decode_fec |
| | | ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); |
| | | |
| | | /** Decode an Opus packet with floating point output. |
| | | * @param [in] st <tt>OpusDecoder*</tt>: Decoder state |
| | | * @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss |
| | | * @param [in] len <tt>opus_int32</tt>: Number of bytes in payload |
| | | * @param [out] pcm <tt>float*</tt>: Output signal (interleaved if 2 channels). length |
| | | * is frame_size*channels*sizeof(float) |
| | | * @param [in] frame_size Number of samples per channel of available space in \a pcm. |
| | | * If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will |
| | | * not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1), |
| | | * then frame_size needs to be exactly the duration of audio that is missing, otherwise the |
| | | * decoder will not be in the optimal state to decode the next incoming packet. For the PLC and |
| | | * FEC cases, frame_size <b>must</b> be a multiple of 2.5 ms. |
| | | * @param [in] decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band forward error correction data be |
| | | * decoded. If no such data is available the frame is decoded as if it were lost. |
| | | * @returns Number of decoded samples or @ref opus_errorcodes |
| | | */ |
| | | OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode_float( |
| | | OpusDecoder *st, |
| | | const unsigned char *data, |
| | | opus_int32 len, |
| | | float *pcm, |
| | | int frame_size, |
| | | int decode_fec |
| | | ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); |
| | | |
| | | /** Perform a CTL function on an Opus decoder. |
| | | * |
| | | * Generally the request and subsequent arguments are generated |
| | | * by a convenience macro. |
| | | * @param st <tt>OpusDecoder*</tt>: Decoder state. |
| | | * @param request This and all remaining parameters should be replaced by one |
| | | * of the convenience macros in @ref opus_genericctls or |
| | | * @ref opus_decoderctls. |
| | | * @see opus_genericctls |
| | | * @see opus_decoderctls |
| | | */ |
| | | OPUS_EXPORT int opus_decoder_ctl(OpusDecoder *st, int request, ...) OPUS_ARG_NONNULL(1); |
| | | |
| | | /** Frees an <code>OpusDecoder</code> allocated by opus_decoder_create(). |
| | | * @param[in] st <tt>OpusDecoder*</tt>: State to be freed. |
| | | */ |
| | | OPUS_EXPORT void opus_decoder_destroy(OpusDecoder *st); |
| | | |
| | | /** Parse an opus packet into one or more frames. |
| | | * Opus_decode will perform this operation internally so most applications do |
| | | * not need to use this function. |
| | | * This function does not copy the frames, the returned pointers are pointers into |
| | | * the input packet. |
| | | * @param [in] data <tt>char*</tt>: Opus packet to be parsed |
| | | * @param [in] len <tt>opus_int32</tt>: size of data |
| | | * @param [out] out_toc <tt>char*</tt>: TOC pointer |
| | | * @param [out] frames <tt>char*[48]</tt> encapsulated frames |
| | | * @param [out] size <tt>opus_int16[48]</tt> sizes of the encapsulated frames |
| | | * @param [out] payload_offset <tt>int*</tt>: returns the position of the payload within the packet (in bytes) |
| | | * @returns number of frames |
| | | */ |
| | | OPUS_EXPORT int opus_packet_parse( |
| | | const unsigned char *data, |
| | | opus_int32 len, |
| | | unsigned char *out_toc, |
| | | const unsigned char *frames[48], |
| | | opus_int16 size[48], |
| | | int *payload_offset |
| | | ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); |
| | | |
| | | /** Gets the bandwidth of an Opus packet. |
| | | * @param [in] data <tt>char*</tt>: Opus packet |
| | | * @retval OPUS_BANDWIDTH_NARROWBAND Narrowband (4kHz bandpass) |
| | | * @retval OPUS_BANDWIDTH_MEDIUMBAND Mediumband (6kHz bandpass) |
| | | * @retval OPUS_BANDWIDTH_WIDEBAND Wideband (8kHz bandpass) |
| | | * @retval OPUS_BANDWIDTH_SUPERWIDEBAND Superwideband (12kHz bandpass) |
| | | * @retval OPUS_BANDWIDTH_FULLBAND Fullband (20kHz bandpass) |
| | | * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type |
| | | */ |
| | | OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_bandwidth(const unsigned char *data) OPUS_ARG_NONNULL(1); |
| | | |
| | | /** Gets the number of samples per frame from an Opus packet. |
| | | * @param [in] data <tt>char*</tt>: Opus packet. |
| | | * This must contain at least one byte of |
| | | * data. |
| | | * @param [in] Fs <tt>opus_int32</tt>: Sampling rate in Hz. |
| | | * This must be a multiple of 400, or |
| | | * inaccurate results will be returned. |
| | | * @returns Number of samples per frame. |
| | | */ |
| | | OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_samples_per_frame(const unsigned char *data, opus_int32 Fs) OPUS_ARG_NONNULL(1); |
| | | |
| | | /** Gets the number of channels from an Opus packet. |
| | | * @param [in] data <tt>char*</tt>: Opus packet |
| | | * @returns Number of channels |
| | | * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type |
| | | */ |
| | | OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_channels(const unsigned char *data) OPUS_ARG_NONNULL(1); |
| | | |
| | | /** Gets the number of frames in an Opus packet. |
| | | * @param [in] packet <tt>char*</tt>: Opus packet |
| | | * @param [in] len <tt>opus_int32</tt>: Length of packet |
| | | * @returns Number of frames |
| | | * @retval OPUS_BAD_ARG Insufficient data was passed to the function |
| | | * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type |
| | | */ |
| | | OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len) OPUS_ARG_NONNULL(1); |
| | | |
| | | /** Gets the number of samples of an Opus packet. |
| | | * @param [in] packet <tt>char*</tt>: Opus packet |
| | | * @param [in] len <tt>opus_int32</tt>: Length of packet |
| | | * @param [in] Fs <tt>opus_int32</tt>: Sampling rate in Hz. |
| | | * This must be a multiple of 400, or |
| | | * inaccurate results will be returned. |
| | | * @returns Number of samples |
| | | * @retval OPUS_BAD_ARG Insufficient data was passed to the function |
| | | * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type |
| | | */ |
| | | OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_samples(const unsigned char packet[], opus_int32 len, opus_int32 Fs) OPUS_ARG_NONNULL(1); |
| | | |
| | | /** Gets the number of samples of an Opus packet. |
| | | * @param [in] dec <tt>OpusDecoder*</tt>: Decoder state |
| | | * @param [in] packet <tt>char*</tt>: Opus packet |
| | | * @param [in] len <tt>opus_int32</tt>: Length of packet |
| | | * @returns Number of samples |
| | | * @retval OPUS_BAD_ARG Insufficient data was passed to the function |
| | | * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type |
| | | */ |
| | | OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decoder_get_nb_samples(const OpusDecoder *dec, const unsigned char packet[], opus_int32 len) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2); |
| | | |
| | | /** Applies soft-clipping to bring a float signal within the [-1,1] range. If |
| | | * the signal is already in that range, nothing is done. If there are values |
| | | * outside of [-1,1], then the signal is clipped as smoothly as possible to |
| | | * both fit in the range and avoid creating excessive distortion in the |
| | | * process. |
| | | * @param [in,out] pcm <tt>float*</tt>: Input PCM and modified PCM |
| | | * @param [in] frame_size <tt>int</tt> Number of samples per channel to process |
| | | * @param [in] channels <tt>int</tt>: Number of channels |
| | | * @param [in,out] softclip_mem <tt>float*</tt>: State memory for the soft clipping process (one float per channel, initialized to zero) |
| | | */ |
| | | OPUS_EXPORT void opus_pcm_soft_clip(float *pcm, int frame_size, int channels, float *softclip_mem); |
| | | |
| | | |
| | | /**@}*/ |
| | | |
| | | /** @defgroup opus_repacketizer Repacketizer |
| | | * @{ |
| | | * |
| | | * The repacketizer can be used to merge multiple Opus packets into a single |
| | | * packet or alternatively to split Opus packets that have previously been |
| | | * merged. Splitting valid Opus packets is always guaranteed to succeed, |
| | | * whereas merging valid packets only succeeds if all frames have the same |
| | | * mode, bandwidth, and frame size, and when the total duration of the merged |
| | | * packet is no more than 120 ms. The 120 ms limit comes from the |
| | | * specification and limits decoder memory requirements at a point where |
| | | * framing overhead becomes negligible. |
| | | * |
| | | * The repacketizer currently only operates on elementary Opus |
| | | * streams. It will not manipualte multistream packets successfully, except in |
| | | * the degenerate case where they consist of data from a single stream. |
| | | * |
| | | * The repacketizing process starts with creating a repacketizer state, either |
| | | * by calling opus_repacketizer_create() or by allocating the memory yourself, |
| | | * e.g., |
| | | * @code |
| | | * OpusRepacketizer *rp; |
| | | * rp = (OpusRepacketizer*)malloc(opus_repacketizer_get_size()); |
| | | * if (rp != NULL) |
| | | * opus_repacketizer_init(rp); |
| | | * @endcode |
| | | * |
| | | * Then the application should submit packets with opus_repacketizer_cat(), |
| | | * extract new packets with opus_repacketizer_out() or |
| | | * opus_repacketizer_out_range(), and then reset the state for the next set of |
| | | * input packets via opus_repacketizer_init(). |
| | | * |
| | | * For example, to split a sequence of packets into individual frames: |
| | | * @code |
| | | * unsigned char *data; |
| | | * int len; |
| | | * while (get_next_packet(&data, &len)) |
| | | * { |
| | | * unsigned char out[1276]; |
| | | * opus_int32 out_len; |
| | | * int nb_frames; |
| | | * int err; |
| | | * int i; |
| | | * err = opus_repacketizer_cat(rp, data, len); |
| | | * if (err != OPUS_OK) |
| | | * { |
| | | * release_packet(data); |
| | | * return err; |
| | | * } |
| | | * nb_frames = opus_repacketizer_get_nb_frames(rp); |
| | | * for (i = 0; i < nb_frames; i++) |
| | | * { |
| | | * out_len = opus_repacketizer_out_range(rp, i, i+1, out, sizeof(out)); |
| | | * if (out_len < 0) |
| | | * { |
| | | * release_packet(data); |
| | | * return (int)out_len; |
| | | * } |
| | | * output_next_packet(out, out_len); |
| | | * } |
| | | * opus_repacketizer_init(rp); |
| | | * release_packet(data); |
| | | * } |
| | | * @endcode |
| | | * |
| | | * Alternatively, to combine a sequence of frames into packets that each |
| | | * contain up to <code>TARGET_DURATION_MS</code> milliseconds of data: |
| | | * @code |
| | | * // The maximum number of packets with duration TARGET_DURATION_MS occurs |
| | | * // when the frame size is 2.5 ms, for a total of (TARGET_DURATION_MS*2/5) |
| | | * // packets. |
| | | * unsigned char *data[(TARGET_DURATION_MS*2/5)+1]; |
| | | * opus_int32 len[(TARGET_DURATION_MS*2/5)+1]; |
| | | * int nb_packets; |
| | | * unsigned char out[1277*(TARGET_DURATION_MS*2/2)]; |
| | | * opus_int32 out_len; |
| | | * int prev_toc; |
| | | * nb_packets = 0; |
| | | * while (get_next_packet(data+nb_packets, len+nb_packets)) |
| | | * { |
| | | * int nb_frames; |
| | | * int err; |
| | | * nb_frames = opus_packet_get_nb_frames(data[nb_packets], len[nb_packets]); |
| | | * if (nb_frames < 1) |
| | | * { |
| | | * release_packets(data, nb_packets+1); |
| | | * return nb_frames; |
| | | * } |
| | | * nb_frames += opus_repacketizer_get_nb_frames(rp); |
| | | * // If adding the next packet would exceed our target, or it has an |
| | | * // incompatible TOC sequence, output the packets we already have before |
| | | * // submitting it. |
| | | * // N.B., The nb_packets > 0 check ensures we've submitted at least one |
| | | * // packet since the last call to opus_repacketizer_init(). Otherwise a |
| | | * // single packet longer than TARGET_DURATION_MS would cause us to try to |
| | | * // output an (invalid) empty packet. It also ensures that prev_toc has |
| | | * // been set to a valid value. Additionally, len[nb_packets] > 0 is |
| | | * // guaranteed by the call to opus_packet_get_nb_frames() above, so the |
| | | * // reference to data[nb_packets][0] should be valid. |
| | | * if (nb_packets > 0 && ( |
| | | * ((prev_toc & 0xFC) != (data[nb_packets][0] & 0xFC)) || |
| | | * opus_packet_get_samples_per_frame(data[nb_packets], 48000)*nb_frames > |
| | | * TARGET_DURATION_MS*48)) |
| | | * { |
| | | * out_len = opus_repacketizer_out(rp, out, sizeof(out)); |
| | | * if (out_len < 0) |
| | | * { |
| | | * release_packets(data, nb_packets+1); |
| | | * return (int)out_len; |
| | | * } |
| | | * output_next_packet(out, out_len); |
| | | * opus_repacketizer_init(rp); |
| | | * release_packets(data, nb_packets); |
| | | * data[0] = data[nb_packets]; |
| | | * len[0] = len[nb_packets]; |
| | | * nb_packets = 0; |
| | | * } |
| | | * err = opus_repacketizer_cat(rp, data[nb_packets], len[nb_packets]); |
| | | * if (err != OPUS_OK) |
| | | * { |
| | | * release_packets(data, nb_packets+1); |
| | | * return err; |
| | | * } |
| | | * prev_toc = data[nb_packets][0]; |
| | | * nb_packets++; |
| | | * } |
| | | * // Output the final, partial packet. |
| | | * if (nb_packets > 0) |
| | | * { |
| | | * out_len = opus_repacketizer_out(rp, out, sizeof(out)); |
| | | * release_packets(data, nb_packets); |
| | | * if (out_len < 0) |
| | | * return (int)out_len; |
| | | * output_next_packet(out, out_len); |
| | | * } |
| | | * @endcode |
| | | * |
| | | * An alternate way of merging packets is to simply call opus_repacketizer_cat() |
| | | * unconditionally until it fails. At that point, the merged packet can be |
| | | * obtained with opus_repacketizer_out() and the input packet for which |
| | | * opus_repacketizer_cat() needs to be re-added to a newly reinitialized |
| | | * repacketizer state. |
| | | */ |
| | | |
| | | typedef struct OpusRepacketizer OpusRepacketizer; |
| | | |
| | | /** Gets the size of an <code>OpusRepacketizer</code> structure. |
| | | * @returns The size in bytes. |
| | | */ |
| | | OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_repacketizer_get_size(void); |
| | | |
| | | /** (Re)initializes a previously allocated repacketizer state. |
| | | * The state must be at least the size returned by opus_repacketizer_get_size(). |
| | | * This can be used for applications which use their own allocator instead of |
| | | * malloc(). |
| | | * It must also be called to reset the queue of packets waiting to be |
| | | * repacketized, which is necessary if the maximum packet duration of 120 ms |
| | | * is reached or if you wish to submit packets with a different Opus |
| | | * configuration (coding mode, audio bandwidth, frame size, or channel count). |
| | | * Failure to do so will prevent a new packet from being added with |
| | | * opus_repacketizer_cat(). |
| | | * @see opus_repacketizer_create |
| | | * @see opus_repacketizer_get_size |
| | | * @see opus_repacketizer_cat |
| | | * @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state to |
| | | * (re)initialize. |
| | | * @returns A pointer to the same repacketizer state that was passed in. |
| | | */ |
| | | OPUS_EXPORT OpusRepacketizer *opus_repacketizer_init(OpusRepacketizer *rp) OPUS_ARG_NONNULL(1); |
| | | |
| | | /** Allocates memory and initializes the new repacketizer with |
| | | * opus_repacketizer_init(). |
| | | */ |
| | | OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusRepacketizer *opus_repacketizer_create(void); |
| | | |
| | | /** Frees an <code>OpusRepacketizer</code> allocated by |
| | | * opus_repacketizer_create(). |
| | | * @param[in] rp <tt>OpusRepacketizer*</tt>: State to be freed. |
| | | */ |
| | | OPUS_EXPORT void opus_repacketizer_destroy(OpusRepacketizer *rp); |
| | | |
| | | /** Add a packet to the current repacketizer state. |
| | | * This packet must match the configuration of any packets already submitted |
| | | * for repacketization since the last call to opus_repacketizer_init(). |
| | | * This means that it must have the same coding mode, audio bandwidth, frame |
| | | * size, and channel count. |
| | | * This can be checked in advance by examining the top 6 bits of the first |
| | | * byte of the packet, and ensuring they match the top 6 bits of the first |
| | | * byte of any previously submitted packet. |
| | | * The total duration of audio in the repacketizer state also must not exceed |
| | | * 120 ms, the maximum duration of a single packet, after adding this packet. |
| | | * |
| | | * The contents of the current repacketizer state can be extracted into new |
| | | * packets using opus_repacketizer_out() or opus_repacketizer_out_range(). |
| | | * |
| | | * In order to add a packet with a different configuration or to add more |
| | | * audio beyond 120 ms, you must clear the repacketizer state by calling |
| | | * opus_repacketizer_init(). |
| | | * If a packet is too large to add to the current repacketizer state, no part |
| | | * of it is added, even if it contains multiple frames, some of which might |
| | | * fit. |
| | | * If you wish to be able to add parts of such packets, you should first use |
| | | * another repacketizer to split the packet into pieces and add them |
| | | * individually. |
| | | * @see opus_repacketizer_out_range |
| | | * @see opus_repacketizer_out |
| | | * @see opus_repacketizer_init |
| | | * @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state to which to |
| | | * add the packet. |
| | | * @param[in] data <tt>const unsigned char*</tt>: The packet data. |
| | | * The application must ensure |
| | | * this pointer remains valid |
| | | * until the next call to |
| | | * opus_repacketizer_init() or |
| | | * opus_repacketizer_destroy(). |
| | | * @param len <tt>opus_int32</tt>: The number of bytes in the packet data. |
| | | * @returns An error code indicating whether or not the operation succeeded. |
| | | * @retval #OPUS_OK The packet's contents have been added to the repacketizer |
| | | * state. |
| | | * @retval #OPUS_INVALID_PACKET The packet did not have a valid TOC sequence, |
| | | * the packet's TOC sequence was not compatible |
| | | * with previously submitted packets (because |
| | | * the coding mode, audio bandwidth, frame size, |
| | | * or channel count did not match), or adding |
| | | * this packet would increase the total amount of |
| | | * audio stored in the repacketizer state to more |
| | | * than 120 ms. |
| | | */ |
| | | OPUS_EXPORT int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data, opus_int32 len) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2); |
| | | |
| | | |
| | | /** Construct a new packet from data previously submitted to the repacketizer |
| | | * state via opus_repacketizer_cat(). |
| | | * @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state from which to |
| | | * construct the new packet. |
| | | * @param begin <tt>int</tt>: The index of the first frame in the current |
| | | * repacketizer state to include in the output. |
| | | * @param end <tt>int</tt>: One past the index of the last frame in the |
| | | * current repacketizer state to include in the |
| | | * output. |
| | | * @param[out] data <tt>const unsigned char*</tt>: The buffer in which to |
| | | * store the output packet. |
| | | * @param maxlen <tt>opus_int32</tt>: The maximum number of bytes to store in |
| | | * the output buffer. In order to guarantee |
| | | * success, this should be at least |
| | | * <code>1276</code> for a single frame, |
| | | * or for multiple frames, |
| | | * <code>1277*(end-begin)</code>. |
| | | * However, <code>1*(end-begin)</code> plus |
| | | * the size of all packet data submitted to |
| | | * the repacketizer since the last call to |
| | | * opus_repacketizer_init() or |
| | | * opus_repacketizer_create() is also |
| | | * sufficient, and possibly much smaller. |
| | | * @returns The total size of the output packet on success, or an error code |
| | | * on failure. |
| | | * @retval #OPUS_BAD_ARG <code>[begin,end)</code> was an invalid range of |
| | | * frames (begin < 0, begin >= end, or end > |
| | | * opus_repacketizer_get_nb_frames()). |
| | | * @retval #OPUS_BUFFER_TOO_SMALL \a maxlen was insufficient to contain the |
| | | * complete output packet. |
| | | */ |
| | | OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_repacketizer_out_range(OpusRepacketizer *rp, int begin, int end, unsigned char *data, opus_int32 maxlen) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); |
| | | |
| | | /** Return the total number of frames contained in packet data submitted to |
| | | * the repacketizer state so far via opus_repacketizer_cat() since the last |
| | | * call to opus_repacketizer_init() or opus_repacketizer_create(). |
| | | * This defines the valid range of packets that can be extracted with |
| | | * opus_repacketizer_out_range() or opus_repacketizer_out(). |
| | | * @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state containing the |
| | | * frames. |
| | | * @returns The total number of frames contained in the packet data submitted |
| | | * to the repacketizer state. |
| | | */ |
| | | OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_repacketizer_get_nb_frames(OpusRepacketizer *rp) OPUS_ARG_NONNULL(1); |
| | | |
| | | /** Construct a new packet from data previously submitted to the repacketizer |
| | | * state via opus_repacketizer_cat(). |
| | | * This is a convenience routine that returns all the data submitted so far |
| | | * in a single packet. |
| | | * It is equivalent to calling |
| | | * @code |
| | | * opus_repacketizer_out_range(rp, 0, opus_repacketizer_get_nb_frames(rp), |
| | | * data, maxlen) |
| | | * @endcode |
| | | * @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state from which to |
| | | * construct the new packet. |
| | | * @param[out] data <tt>const unsigned char*</tt>: The buffer in which to |
| | | * store the output packet. |
| | | * @param maxlen <tt>opus_int32</tt>: The maximum number of bytes to store in |
| | | * the output buffer. In order to guarantee |
| | | * success, this should be at least |
| | | * <code>1277*opus_repacketizer_get_nb_frames(rp)</code>. |
| | | * However, |
| | | * <code>1*opus_repacketizer_get_nb_frames(rp)</code> |
| | | * plus the size of all packet data |
| | | * submitted to the repacketizer since the |
| | | * last call to opus_repacketizer_init() or |
| | | * opus_repacketizer_create() is also |
| | | * sufficient, and possibly much smaller. |
| | | * @returns The total size of the output packet on success, or an error code |
| | | * on failure. |
| | | * @retval #OPUS_BUFFER_TOO_SMALL \a maxlen was insufficient to contain the |
| | | * complete output packet. |
| | | */ |
| | | OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_repacketizer_out(OpusRepacketizer *rp, unsigned char *data, opus_int32 maxlen) OPUS_ARG_NONNULL(1); |
| | | |
| | | /** Pads a given Opus packet to a larger size (possibly changing the TOC sequence). |
| | | * @param[in,out] data <tt>const unsigned char*</tt>: The buffer containing the |
| | | * packet to pad. |
| | | * @param len <tt>opus_int32</tt>: The size of the packet. |
| | | * This must be at least 1. |
| | | * @param new_len <tt>opus_int32</tt>: The desired size of the packet after padding. |
| | | * This must be at least as large as len. |
| | | * @returns an error code |
| | | * @retval #OPUS_OK \a on success. |
| | | * @retval #OPUS_BAD_ARG \a len was less than 1 or new_len was less than len. |
| | | * @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet. |
| | | */ |
| | | OPUS_EXPORT int opus_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len); |
| | | |
| | | /** Remove all padding from a given Opus packet and rewrite the TOC sequence to |
| | | * minimize space usage. |
| | | * @param[in,out] data <tt>const unsigned char*</tt>: The buffer containing the |
| | | * packet to strip. |
| | | * @param len <tt>opus_int32</tt>: The size of the packet. |
| | | * This must be at least 1. |
| | | * @returns The new size of the output packet on success, or an error code |
| | | * on failure. |
| | | * @retval #OPUS_BAD_ARG \a len was less than 1. |
| | | * @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet. |
| | | */ |
| | | OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_packet_unpad(unsigned char *data, opus_int32 len); |
| | | |
| | | /** Pads a given Opus multi-stream packet to a larger size (possibly changing the TOC sequence). |
| | | * @param[in,out] data <tt>const unsigned char*</tt>: The buffer containing the |
| | | * packet to pad. |
| | | * @param len <tt>opus_int32</tt>: The size of the packet. |
| | | * This must be at least 1. |
| | | * @param new_len <tt>opus_int32</tt>: The desired size of the packet after padding. |
| | | * This must be at least 1. |
| | | * @param nb_streams <tt>opus_int32</tt>: The number of streams (not channels) in the packet. |
| | | * This must be at least as large as len. |
| | | * @returns an error code |
| | | * @retval #OPUS_OK \a on success. |
| | | * @retval #OPUS_BAD_ARG \a len was less than 1. |
| | | * @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet. |
| | | */ |
| | | OPUS_EXPORT int opus_multistream_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len, int nb_streams); |
| | | |
| | | /** Remove all padding from a given Opus multi-stream packet and rewrite the TOC sequence to |
| | | * minimize space usage. |
| | | * @param[in,out] data <tt>const unsigned char*</tt>: The buffer containing the |
| | | * packet to strip. |
| | | * @param len <tt>opus_int32</tt>: The size of the packet. |
| | | * This must be at least 1. |
| | | * @param nb_streams <tt>opus_int32</tt>: The number of streams (not channels) in the packet. |
| | | * This must be at least 1. |
| | | * @returns The new size of the output packet on success, or an error code |
| | | * on failure. |
| | | * @retval #OPUS_BAD_ARG \a len was less than 1 or new_len was less than len. |
| | | * @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet. |
| | | */ |
| | | OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_packet_unpad(unsigned char *data, opus_int32 len, int nb_streams); |
| | | |
| | | /**@}*/ |
| | | |
| | | #ifdef __cplusplus |
| | | } |
| | | #endif |
| | | |
| | | #endif /* OPUS_H */ |
New file |
| | |
| | | /* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited |
| | | Written by Jean-Marc Valin and Koen Vos */ |
| | | /* |
| | | 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. |
| | | |
| | | 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. |
| | | */ |
| | | |
| | | /** |
| | | * @file opus_defines.h |
| | | * @brief Opus reference implementation constants |
| | | */ |
| | | |
| | | #ifndef OPUS_DEFINES_H |
| | | #define OPUS_DEFINES_H |
| | | |
| | | #include "opus_types.h" |
| | | |
| | | #ifdef __cplusplus |
| | | extern "C" { |
| | | #endif |
| | | |
| | | /** @defgroup opus_errorcodes Error codes |
| | | * @{ |
| | | */ |
| | | /** No error @hideinitializer*/ |
| | | #define OPUS_OK 0 |
| | | /** One or more invalid/out of range arguments @hideinitializer*/ |
| | | #define OPUS_BAD_ARG -1 |
| | | /** Not enough bytes allocated in the buffer @hideinitializer*/ |
| | | #define OPUS_BUFFER_TOO_SMALL -2 |
| | | /** An internal error was detected @hideinitializer*/ |
| | | #define OPUS_INTERNAL_ERROR -3 |
| | | /** The compressed data passed is corrupted @hideinitializer*/ |
| | | #define OPUS_INVALID_PACKET -4 |
| | | /** Invalid/unsupported request number @hideinitializer*/ |
| | | #define OPUS_UNIMPLEMENTED -5 |
| | | /** An encoder or decoder structure is invalid or already freed @hideinitializer*/ |
| | | #define OPUS_INVALID_STATE -6 |
| | | /** Memory allocation has failed @hideinitializer*/ |
| | | #define OPUS_ALLOC_FAIL -7 |
| | | /**@}*/ |
| | | |
| | | /** @cond OPUS_INTERNAL_DOC */ |
| | | /**Export control for opus functions */ |
| | | |
| | | #ifndef OPUS_EXPORT |
| | | # if defined(WIN32) |
| | | # if defined(OPUS_BUILD) && defined(DLL_EXPORT) |
| | | # define OPUS_EXPORT __declspec(dllexport) |
| | | # else |
| | | # define OPUS_EXPORT |
| | | # endif |
| | | # elif defined(__GNUC__) && defined(OPUS_BUILD) |
| | | # define OPUS_EXPORT __attribute__ ((visibility ("default"))) |
| | | # else |
| | | # define OPUS_EXPORT |
| | | # endif |
| | | #endif |
| | | |
| | | # if !defined(OPUS_GNUC_PREREQ) |
| | | # if defined(__GNUC__)&&defined(__GNUC_MINOR__) |
| | | # define OPUS_GNUC_PREREQ(_maj,_min) \ |
| | | ((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min)) |
| | | # else |
| | | # define OPUS_GNUC_PREREQ(_maj,_min) 0 |
| | | # endif |
| | | # endif |
| | | |
| | | #if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) ) |
| | | # if OPUS_GNUC_PREREQ(3,0) |
| | | # define OPUS_RESTRICT __restrict__ |
| | | # elif (defined(_MSC_VER) && _MSC_VER >= 1400) |
| | | # define OPUS_RESTRICT __restrict |
| | | # else |
| | | # define OPUS_RESTRICT |
| | | # endif |
| | | #else |
| | | # define OPUS_RESTRICT restrict |
| | | #endif |
| | | |
| | | #if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) ) |
| | | # if OPUS_GNUC_PREREQ(2,7) |
| | | # define OPUS_INLINE __inline__ |
| | | # elif (defined(_MSC_VER)) |
| | | # define OPUS_INLINE __inline |
| | | # else |
| | | # define OPUS_INLINE |
| | | # endif |
| | | #else |
| | | # define OPUS_INLINE inline |
| | | #endif |
| | | |
| | | /**Warning attributes for opus functions |
| | | * NONNULL is not used in OPUS_BUILD to avoid the compiler optimizing out |
| | | * some paranoid null checks. */ |
| | | #if defined(__GNUC__) && OPUS_GNUC_PREREQ(3, 4) |
| | | # define OPUS_WARN_UNUSED_RESULT __attribute__ ((__warn_unused_result__)) |
| | | #else |
| | | # define OPUS_WARN_UNUSED_RESULT |
| | | #endif |
| | | #if !defined(OPUS_BUILD) && defined(__GNUC__) && OPUS_GNUC_PREREQ(3, 4) |
| | | # define OPUS_ARG_NONNULL(_x) __attribute__ ((__nonnull__(_x))) |
| | | #else |
| | | # define OPUS_ARG_NONNULL(_x) |
| | | #endif |
| | | |
| | | /** These are the actual Encoder CTL ID numbers. |
| | | * They should not be used directly by applications. |
| | | * In general, SETs should be even and GETs should be odd.*/ |
| | | #define OPUS_SET_APPLICATION_REQUEST 4000 |
| | | #define OPUS_GET_APPLICATION_REQUEST 4001 |
| | | #define OPUS_SET_BITRATE_REQUEST 4002 |
| | | #define OPUS_GET_BITRATE_REQUEST 4003 |
| | | #define OPUS_SET_MAX_BANDWIDTH_REQUEST 4004 |
| | | #define OPUS_GET_MAX_BANDWIDTH_REQUEST 4005 |
| | | #define OPUS_SET_VBR_REQUEST 4006 |
| | | #define OPUS_GET_VBR_REQUEST 4007 |
| | | #define OPUS_SET_BANDWIDTH_REQUEST 4008 |
| | | #define OPUS_GET_BANDWIDTH_REQUEST 4009 |
| | | #define OPUS_SET_COMPLEXITY_REQUEST 4010 |
| | | #define OPUS_GET_COMPLEXITY_REQUEST 4011 |
| | | #define OPUS_SET_INBAND_FEC_REQUEST 4012 |
| | | #define OPUS_GET_INBAND_FEC_REQUEST 4013 |
| | | #define OPUS_SET_PACKET_LOSS_PERC_REQUEST 4014 |
| | | #define OPUS_GET_PACKET_LOSS_PERC_REQUEST 4015 |
| | | #define OPUS_SET_DTX_REQUEST 4016 |
| | | #define OPUS_GET_DTX_REQUEST 4017 |
| | | #define OPUS_SET_VBR_CONSTRAINT_REQUEST 4020 |
| | | #define OPUS_GET_VBR_CONSTRAINT_REQUEST 4021 |
| | | #define OPUS_SET_FORCE_CHANNELS_REQUEST 4022 |
| | | #define OPUS_GET_FORCE_CHANNELS_REQUEST 4023 |
| | | #define OPUS_SET_SIGNAL_REQUEST 4024 |
| | | #define OPUS_GET_SIGNAL_REQUEST 4025 |
| | | #define OPUS_GET_LOOKAHEAD_REQUEST 4027 |
| | | /* #define OPUS_RESET_STATE 4028 */ |
| | | #define OPUS_GET_SAMPLE_RATE_REQUEST 4029 |
| | | #define OPUS_GET_FINAL_RANGE_REQUEST 4031 |
| | | #define OPUS_GET_PITCH_REQUEST 4033 |
| | | #define OPUS_SET_GAIN_REQUEST 4034 |
| | | #define OPUS_GET_GAIN_REQUEST 4045 /* Should have been 4035 */ |
| | | #define OPUS_SET_LSB_DEPTH_REQUEST 4036 |
| | | #define OPUS_GET_LSB_DEPTH_REQUEST 4037 |
| | | #define OPUS_GET_LAST_PACKET_DURATION_REQUEST 4039 |
| | | #define OPUS_SET_EXPERT_FRAME_DURATION_REQUEST 4040 |
| | | #define OPUS_GET_EXPERT_FRAME_DURATION_REQUEST 4041 |
| | | #define OPUS_SET_PREDICTION_DISABLED_REQUEST 4042 |
| | | #define OPUS_GET_PREDICTION_DISABLED_REQUEST 4043 |
| | | |
| | | /* Don't use 4045, it's already taken by OPUS_GET_GAIN_REQUEST */ |
| | | |
| | | /* Macros to trigger compilation errors when the wrong types are provided to a CTL */ |
| | | #define __opus_check_int(x) (((void)((x) == (opus_int32)0)), (opus_int32)(x)) |
| | | #define __opus_check_int_ptr(ptr) ((ptr) + ((ptr) - (opus_int32*)(ptr))) |
| | | #define __opus_check_uint_ptr(ptr) ((ptr) + ((ptr) - (opus_uint32*)(ptr))) |
| | | #define __opus_check_val16_ptr(ptr) ((ptr) + ((ptr) - (opus_val16*)(ptr))) |
| | | /** @endcond */ |
| | | |
| | | /** @defgroup opus_ctlvalues Pre-defined values for CTL interface |
| | | * @see opus_genericctls, opus_encoderctls |
| | | * @{ |
| | | */ |
| | | /* Values for the various encoder CTLs */ |
| | | #define OPUS_AUTO -1000 /**<Auto/default setting @hideinitializer*/ |
| | | #define OPUS_BITRATE_MAX -1 /**<Maximum bitrate @hideinitializer*/ |
| | | |
| | | /** Best for most VoIP/videoconference applications where listening quality and intelligibility matter most |
| | | * @hideinitializer */ |
| | | #define OPUS_APPLICATION_VOIP 2048 |
| | | /** Best for broadcast/high-fidelity application where the decoded audio should be as close as possible to the input |
| | | * @hideinitializer */ |
| | | #define OPUS_APPLICATION_AUDIO 2049 |
| | | /** Only use when lowest-achievable latency is what matters most. Voice-optimized modes cannot be used. |
| | | * @hideinitializer */ |
| | | #define OPUS_APPLICATION_RESTRICTED_LOWDELAY 2051 |
| | | |
| | | #define OPUS_SIGNAL_VOICE 3001 /**< Signal being encoded is voice */ |
| | | #define OPUS_SIGNAL_MUSIC 3002 /**< Signal being encoded is music */ |
| | | #define OPUS_BANDWIDTH_NARROWBAND 1101 /**< 4 kHz bandpass @hideinitializer*/ |
| | | #define OPUS_BANDWIDTH_MEDIUMBAND 1102 /**< 6 kHz bandpass @hideinitializer*/ |
| | | #define OPUS_BANDWIDTH_WIDEBAND 1103 /**< 8 kHz bandpass @hideinitializer*/ |
| | | #define OPUS_BANDWIDTH_SUPERWIDEBAND 1104 /**<12 kHz bandpass @hideinitializer*/ |
| | | #define OPUS_BANDWIDTH_FULLBAND 1105 /**<20 kHz bandpass @hideinitializer*/ |
| | | |
| | | #define OPUS_FRAMESIZE_ARG 5000 /**< Select frame size from the argument (default) */ |
| | | #define OPUS_FRAMESIZE_2_5_MS 5001 /**< Use 2.5 ms frames */ |
| | | #define OPUS_FRAMESIZE_5_MS 5002 /**< Use 5 ms frames */ |
| | | #define OPUS_FRAMESIZE_10_MS 5003 /**< Use 10 ms frames */ |
| | | #define OPUS_FRAMESIZE_20_MS 5004 /**< Use 20 ms frames */ |
| | | #define OPUS_FRAMESIZE_40_MS 5005 /**< Use 40 ms frames */ |
| | | #define OPUS_FRAMESIZE_60_MS 5006 /**< Use 60 ms frames */ |
| | | |
| | | /**@}*/ |
| | | |
| | | |
| | | /** @defgroup opus_encoderctls Encoder related CTLs |
| | | * |
| | | * These are convenience macros for use with the \c opus_encode_ctl |
| | | * interface. They are used to generate the appropriate series of |
| | | * arguments for that call, passing the correct type, size and so |
| | | * on as expected for each particular request. |
| | | * |
| | | * Some usage examples: |
| | | * |
| | | * @code |
| | | * int ret; |
| | | * ret = opus_encoder_ctl(enc_ctx, OPUS_SET_BANDWIDTH(OPUS_AUTO)); |
| | | * if (ret != OPUS_OK) return ret; |
| | | * |
| | | * opus_int32 rate; |
| | | * opus_encoder_ctl(enc_ctx, OPUS_GET_BANDWIDTH(&rate)); |
| | | * |
| | | * opus_encoder_ctl(enc_ctx, OPUS_RESET_STATE); |
| | | * @endcode |
| | | * |
| | | * @see opus_genericctls, opus_encoder |
| | | * @{ |
| | | */ |
| | | |
| | | /** Configures the encoder's computational complexity. |
| | | * The supported range is 0-10 inclusive with 10 representing the highest complexity. |
| | | * @see OPUS_GET_COMPLEXITY |
| | | * @param[in] x <tt>opus_int32</tt>: Allowed values: 0-10, inclusive. |
| | | * |
| | | * @hideinitializer */ |
| | | #define OPUS_SET_COMPLEXITY(x) OPUS_SET_COMPLEXITY_REQUEST, __opus_check_int(x) |
| | | /** Gets the encoder's complexity configuration. |
| | | * @see OPUS_SET_COMPLEXITY |
| | | * @param[out] x <tt>opus_int32 *</tt>: Returns a value in the range 0-10, |
| | | * inclusive. |
| | | * @hideinitializer */ |
| | | #define OPUS_GET_COMPLEXITY(x) OPUS_GET_COMPLEXITY_REQUEST, __opus_check_int_ptr(x) |
| | | |
| | | /** Configures the bitrate in the encoder. |
| | | * Rates from 500 to 512000 bits per second are meaningful, as well as the |
| | | * special values #OPUS_AUTO and #OPUS_BITRATE_MAX. |
| | | * The value #OPUS_BITRATE_MAX can be used to cause the codec to use as much |
| | | * rate as it can, which is useful for controlling the rate by adjusting the |
| | | * output buffer size. |
| | | * @see OPUS_GET_BITRATE |
| | | * @param[in] x <tt>opus_int32</tt>: Bitrate in bits per second. The default |
| | | * is determined based on the number of |
| | | * channels and the input sampling rate. |
| | | * @hideinitializer */ |
| | | #define OPUS_SET_BITRATE(x) OPUS_SET_BITRATE_REQUEST, __opus_check_int(x) |
| | | /** Gets the encoder's bitrate configuration. |
| | | * @see OPUS_SET_BITRATE |
| | | * @param[out] x <tt>opus_int32 *</tt>: Returns the bitrate in bits per second. |
| | | * The default is determined based on the |
| | | * number of channels and the input |
| | | * sampling rate. |
| | | * @hideinitializer */ |
| | | #define OPUS_GET_BITRATE(x) OPUS_GET_BITRATE_REQUEST, __opus_check_int_ptr(x) |
| | | |
| | | /** Enables or disables variable bitrate (VBR) in the encoder. |
| | | * The configured bitrate may not be met exactly because frames must |
| | | * be an integer number of bytes in length. |
| | | * @see OPUS_GET_VBR |
| | | * @see OPUS_SET_VBR_CONSTRAINT |
| | | * @param[in] x <tt>opus_int32</tt>: Allowed values: |
| | | * <dl> |
| | | * <dt>0</dt><dd>Hard CBR. For LPC/hybrid modes at very low bit-rate, this can |
| | | * cause noticeable quality degradation.</dd> |
| | | * <dt>1</dt><dd>VBR (default). The exact type of VBR is controlled by |
| | | * #OPUS_SET_VBR_CONSTRAINT.</dd> |
| | | * </dl> |
| | | * @hideinitializer */ |
| | | #define OPUS_SET_VBR(x) OPUS_SET_VBR_REQUEST, __opus_check_int(x) |
| | | /** Determine if variable bitrate (VBR) is enabled in the encoder. |
| | | * @see OPUS_SET_VBR |
| | | * @see OPUS_GET_VBR_CONSTRAINT |
| | | * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values: |
| | | * <dl> |
| | | * <dt>0</dt><dd>Hard CBR.</dd> |
| | | * <dt>1</dt><dd>VBR (default). The exact type of VBR may be retrieved via |
| | | * #OPUS_GET_VBR_CONSTRAINT.</dd> |
| | | * </dl> |
| | | * @hideinitializer */ |
| | | #define OPUS_GET_VBR(x) OPUS_GET_VBR_REQUEST, __opus_check_int_ptr(x) |
| | | |
| | | /** Enables or disables constrained VBR in the encoder. |
| | | * This setting is ignored when the encoder is in CBR mode. |
| | | * @warning Only the MDCT mode of Opus currently heeds the constraint. |
| | | * Speech mode ignores it completely, hybrid mode may fail to obey it |
| | | * if the LPC layer uses more bitrate than the constraint would have |
| | | * permitted. |
| | | * @see OPUS_GET_VBR_CONSTRAINT |
| | | * @see OPUS_SET_VBR |
| | | * @param[in] x <tt>opus_int32</tt>: Allowed values: |
| | | * <dl> |
| | | * <dt>0</dt><dd>Unconstrained VBR.</dd> |
| | | * <dt>1</dt><dd>Constrained VBR (default). This creates a maximum of one |
| | | * frame of buffering delay assuming a transport with a |
| | | * serialization speed of the nominal bitrate.</dd> |
| | | * </dl> |
| | | * @hideinitializer */ |
| | | #define OPUS_SET_VBR_CONSTRAINT(x) OPUS_SET_VBR_CONSTRAINT_REQUEST, __opus_check_int(x) |
| | | /** Determine if constrained VBR is enabled in the encoder. |
| | | * @see OPUS_SET_VBR_CONSTRAINT |
| | | * @see OPUS_GET_VBR |
| | | * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values: |
| | | * <dl> |
| | | * <dt>0</dt><dd>Unconstrained VBR.</dd> |
| | | * <dt>1</dt><dd>Constrained VBR (default).</dd> |
| | | * </dl> |
| | | * @hideinitializer */ |
| | | #define OPUS_GET_VBR_CONSTRAINT(x) OPUS_GET_VBR_CONSTRAINT_REQUEST, __opus_check_int_ptr(x) |
| | | |
| | | /** Configures mono/stereo forcing in the encoder. |
| | | * This can force the encoder to produce packets encoded as either mono or |
| | | * stereo, regardless of the format of the input audio. This is useful when |
| | | * the caller knows that the input signal is currently a mono source embedded |
| | | * in a stereo stream. |
| | | * @see OPUS_GET_FORCE_CHANNELS |
| | | * @param[in] x <tt>opus_int32</tt>: Allowed values: |
| | | * <dl> |
| | | * <dt>#OPUS_AUTO</dt><dd>Not forced (default)</dd> |
| | | * <dt>1</dt> <dd>Forced mono</dd> |
| | | * <dt>2</dt> <dd>Forced stereo</dd> |
| | | * </dl> |
| | | * @hideinitializer */ |
| | | #define OPUS_SET_FORCE_CHANNELS(x) OPUS_SET_FORCE_CHANNELS_REQUEST, __opus_check_int(x) |
| | | /** Gets the encoder's forced channel configuration. |
| | | * @see OPUS_SET_FORCE_CHANNELS |
| | | * @param[out] x <tt>opus_int32 *</tt>: |
| | | * <dl> |
| | | * <dt>#OPUS_AUTO</dt><dd>Not forced (default)</dd> |
| | | * <dt>1</dt> <dd>Forced mono</dd> |
| | | * <dt>2</dt> <dd>Forced stereo</dd> |
| | | * </dl> |
| | | * @hideinitializer */ |
| | | #define OPUS_GET_FORCE_CHANNELS(x) OPUS_GET_FORCE_CHANNELS_REQUEST, __opus_check_int_ptr(x) |
| | | |
| | | /** Configures the maximum bandpass that the encoder will select automatically. |
| | | * Applications should normally use this instead of #OPUS_SET_BANDWIDTH |
| | | * (leaving that set to the default, #OPUS_AUTO). This allows the |
| | | * application to set an upper bound based on the type of input it is |
| | | * providing, but still gives the encoder the freedom to reduce the bandpass |
| | | * when the bitrate becomes too low, for better overall quality. |
| | | * @see OPUS_GET_MAX_BANDWIDTH |
| | | * @param[in] x <tt>opus_int32</tt>: Allowed values: |
| | | * <dl> |
| | | * <dt>OPUS_BANDWIDTH_NARROWBAND</dt> <dd>4 kHz passband</dd> |
| | | * <dt>OPUS_BANDWIDTH_MEDIUMBAND</dt> <dd>6 kHz passband</dd> |
| | | * <dt>OPUS_BANDWIDTH_WIDEBAND</dt> <dd>8 kHz passband</dd> |
| | | * <dt>OPUS_BANDWIDTH_SUPERWIDEBAND</dt><dd>12 kHz passband</dd> |
| | | * <dt>OPUS_BANDWIDTH_FULLBAND</dt> <dd>20 kHz passband (default)</dd> |
| | | * </dl> |
| | | * @hideinitializer */ |
| | | #define OPUS_SET_MAX_BANDWIDTH(x) OPUS_SET_MAX_BANDWIDTH_REQUEST, __opus_check_int(x) |
| | | |
| | | /** Gets the encoder's configured maximum allowed bandpass. |
| | | * @see OPUS_SET_MAX_BANDWIDTH |
| | | * @param[out] x <tt>opus_int32 *</tt>: Allowed values: |
| | | * <dl> |
| | | * <dt>#OPUS_BANDWIDTH_NARROWBAND</dt> <dd>4 kHz passband</dd> |
| | | * <dt>#OPUS_BANDWIDTH_MEDIUMBAND</dt> <dd>6 kHz passband</dd> |
| | | * <dt>#OPUS_BANDWIDTH_WIDEBAND</dt> <dd>8 kHz passband</dd> |
| | | * <dt>#OPUS_BANDWIDTH_SUPERWIDEBAND</dt><dd>12 kHz passband</dd> |
| | | * <dt>#OPUS_BANDWIDTH_FULLBAND</dt> <dd>20 kHz passband (default)</dd> |
| | | * </dl> |
| | | * @hideinitializer */ |
| | | #define OPUS_GET_MAX_BANDWIDTH(x) OPUS_GET_MAX_BANDWIDTH_REQUEST, __opus_check_int_ptr(x) |
| | | |
| | | /** Sets the encoder's bandpass to a specific value. |
| | | * This prevents the encoder from automatically selecting the bandpass based |
| | | * on the available bitrate. If an application knows the bandpass of the input |
| | | * audio it is providing, it should normally use #OPUS_SET_MAX_BANDWIDTH |
| | | * instead, which still gives the encoder the freedom to reduce the bandpass |
| | | * when the bitrate becomes too low, for better overall quality. |
| | | * @see OPUS_GET_BANDWIDTH |
| | | * @param[in] x <tt>opus_int32</tt>: Allowed values: |
| | | * <dl> |
| | | * <dt>#OPUS_AUTO</dt> <dd>(default)</dd> |
| | | * <dt>#OPUS_BANDWIDTH_NARROWBAND</dt> <dd>4 kHz passband</dd> |
| | | * <dt>#OPUS_BANDWIDTH_MEDIUMBAND</dt> <dd>6 kHz passband</dd> |
| | | * <dt>#OPUS_BANDWIDTH_WIDEBAND</dt> <dd>8 kHz passband</dd> |
| | | * <dt>#OPUS_BANDWIDTH_SUPERWIDEBAND</dt><dd>12 kHz passband</dd> |
| | | * <dt>#OPUS_BANDWIDTH_FULLBAND</dt> <dd>20 kHz passband</dd> |
| | | * </dl> |
| | | * @hideinitializer */ |
| | | #define OPUS_SET_BANDWIDTH(x) OPUS_SET_BANDWIDTH_REQUEST, __opus_check_int(x) |
| | | |
| | | /** Configures the type of signal being encoded. |
| | | * This is a hint which helps the encoder's mode selection. |
| | | * @see OPUS_GET_SIGNAL |
| | | * @param[in] x <tt>opus_int32</tt>: Allowed values: |
| | | * <dl> |
| | | * <dt>#OPUS_AUTO</dt> <dd>(default)</dd> |
| | | * <dt>#OPUS_SIGNAL_VOICE</dt><dd>Bias thresholds towards choosing LPC or Hybrid modes.</dd> |
| | | * <dt>#OPUS_SIGNAL_MUSIC</dt><dd>Bias thresholds towards choosing MDCT modes.</dd> |
| | | * </dl> |
| | | * @hideinitializer */ |
| | | #define OPUS_SET_SIGNAL(x) OPUS_SET_SIGNAL_REQUEST, __opus_check_int(x) |
| | | /** Gets the encoder's configured signal type. |
| | | * @see OPUS_SET_SIGNAL |
| | | * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values: |
| | | * <dl> |
| | | * <dt>#OPUS_AUTO</dt> <dd>(default)</dd> |
| | | * <dt>#OPUS_SIGNAL_VOICE</dt><dd>Bias thresholds towards choosing LPC or Hybrid modes.</dd> |
| | | * <dt>#OPUS_SIGNAL_MUSIC</dt><dd>Bias thresholds towards choosing MDCT modes.</dd> |
| | | * </dl> |
| | | * @hideinitializer */ |
| | | #define OPUS_GET_SIGNAL(x) OPUS_GET_SIGNAL_REQUEST, __opus_check_int_ptr(x) |
| | | |
| | | |
| | | /** Configures the encoder's intended application. |
| | | * The initial value is a mandatory argument to the encoder_create function. |
| | | * @see OPUS_GET_APPLICATION |
| | | * @param[in] x <tt>opus_int32</tt>: Returns one of the following values: |
| | | * <dl> |
| | | * <dt>#OPUS_APPLICATION_VOIP</dt> |
| | | * <dd>Process signal for improved speech intelligibility.</dd> |
| | | * <dt>#OPUS_APPLICATION_AUDIO</dt> |
| | | * <dd>Favor faithfulness to the original input.</dd> |
| | | * <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt> |
| | | * <dd>Configure the minimum possible coding delay by disabling certain modes |
| | | * of operation.</dd> |
| | | * </dl> |
| | | * @hideinitializer */ |
| | | #define OPUS_SET_APPLICATION(x) OPUS_SET_APPLICATION_REQUEST, __opus_check_int(x) |
| | | /** Gets the encoder's configured application. |
| | | * @see OPUS_SET_APPLICATION |
| | | * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values: |
| | | * <dl> |
| | | * <dt>#OPUS_APPLICATION_VOIP</dt> |
| | | * <dd>Process signal for improved speech intelligibility.</dd> |
| | | * <dt>#OPUS_APPLICATION_AUDIO</dt> |
| | | * <dd>Favor faithfulness to the original input.</dd> |
| | | * <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt> |
| | | * <dd>Configure the minimum possible coding delay by disabling certain modes |
| | | * of operation.</dd> |
| | | * </dl> |
| | | * @hideinitializer */ |
| | | #define OPUS_GET_APPLICATION(x) OPUS_GET_APPLICATION_REQUEST, __opus_check_int_ptr(x) |
| | | |
| | | /** Gets the total samples of delay added by the entire codec. |
| | | * This can be queried by the encoder and then the provided number of samples can be |
| | | * skipped on from the start of the decoder's output to provide time aligned input |
| | | * and output. From the perspective of a decoding application the real data begins this many |
| | | * samples late. |
| | | * |
| | | * The decoder contribution to this delay is identical for all decoders, but the |
| | | * encoder portion of the delay may vary from implementation to implementation, |
| | | * version to version, or even depend on the encoder's initial configuration. |
| | | * Applications needing delay compensation should call this CTL rather than |
| | | * hard-coding a value. |
| | | * @param[out] x <tt>opus_int32 *</tt>: Number of lookahead samples |
| | | * @hideinitializer */ |
| | | #define OPUS_GET_LOOKAHEAD(x) OPUS_GET_LOOKAHEAD_REQUEST, __opus_check_int_ptr(x) |
| | | |
| | | /** Configures the encoder's use of inband forward error correction (FEC). |
| | | * @note This is only applicable to the LPC layer |
| | | * @see OPUS_GET_INBAND_FEC |
| | | * @param[in] x <tt>opus_int32</tt>: Allowed values: |
| | | * <dl> |
| | | * <dt>0</dt><dd>Disable inband FEC (default).</dd> |
| | | * <dt>1</dt><dd>Enable inband FEC.</dd> |
| | | * </dl> |
| | | * @hideinitializer */ |
| | | #define OPUS_SET_INBAND_FEC(x) OPUS_SET_INBAND_FEC_REQUEST, __opus_check_int(x) |
| | | /** Gets encoder's configured use of inband forward error correction. |
| | | * @see OPUS_SET_INBAND_FEC |
| | | * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values: |
| | | * <dl> |
| | | * <dt>0</dt><dd>Inband FEC disabled (default).</dd> |
| | | * <dt>1</dt><dd>Inband FEC enabled.</dd> |
| | | * </dl> |
| | | * @hideinitializer */ |
| | | #define OPUS_GET_INBAND_FEC(x) OPUS_GET_INBAND_FEC_REQUEST, __opus_check_int_ptr(x) |
| | | |
| | | /** Configures the encoder's expected packet loss percentage. |
| | | * Higher values trigger progressively more loss resistant behavior in the encoder |
| | | * at the expense of quality at a given bitrate in the absence of packet loss, but |
| | | * greater quality under loss. |
| | | * @see OPUS_GET_PACKET_LOSS_PERC |
| | | * @param[in] x <tt>opus_int32</tt>: Loss percentage in the range 0-100, inclusive (default: 0). |
| | | * @hideinitializer */ |
| | | #define OPUS_SET_PACKET_LOSS_PERC(x) OPUS_SET_PACKET_LOSS_PERC_REQUEST, __opus_check_int(x) |
| | | /** Gets the encoder's configured packet loss percentage. |
| | | * @see OPUS_SET_PACKET_LOSS_PERC |
| | | * @param[out] x <tt>opus_int32 *</tt>: Returns the configured loss percentage |
| | | * in the range 0-100, inclusive (default: 0). |
| | | * @hideinitializer */ |
| | | #define OPUS_GET_PACKET_LOSS_PERC(x) OPUS_GET_PACKET_LOSS_PERC_REQUEST, __opus_check_int_ptr(x) |
| | | |
| | | /** Configures the encoder's use of discontinuous transmission (DTX). |
| | | * @note This is only applicable to the LPC layer |
| | | * @see OPUS_GET_DTX |
| | | * @param[in] x <tt>opus_int32</tt>: Allowed values: |
| | | * <dl> |
| | | * <dt>0</dt><dd>Disable DTX (default).</dd> |
| | | * <dt>1</dt><dd>Enabled DTX.</dd> |
| | | * </dl> |
| | | * @hideinitializer */ |
| | | #define OPUS_SET_DTX(x) OPUS_SET_DTX_REQUEST, __opus_check_int(x) |
| | | /** Gets encoder's configured use of discontinuous transmission. |
| | | * @see OPUS_SET_DTX |
| | | * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values: |
| | | * <dl> |
| | | * <dt>0</dt><dd>DTX disabled (default).</dd> |
| | | * <dt>1</dt><dd>DTX enabled.</dd> |
| | | * </dl> |
| | | * @hideinitializer */ |
| | | #define OPUS_GET_DTX(x) OPUS_GET_DTX_REQUEST, __opus_check_int_ptr(x) |
| | | /** Configures the depth of signal being encoded. |
| | | * |
| | | * This is a hint which helps the encoder identify silence and near-silence. |
| | | * It represents the number of significant bits of linear intensity below |
| | | * which the signal contains ignorable quantization or other noise. |
| | | * |
| | | * For example, OPUS_SET_LSB_DEPTH(14) would be an appropriate setting |
| | | * for G.711 u-law input. OPUS_SET_LSB_DEPTH(16) would be appropriate |
| | | * for 16-bit linear pcm input with opus_encode_float(). |
| | | * |
| | | * When using opus_encode() instead of opus_encode_float(), or when libopus |
| | | * is compiled for fixed-point, the encoder uses the minimum of the value |
| | | * set here and the value 16. |
| | | * |
| | | * @see OPUS_GET_LSB_DEPTH |
| | | * @param[in] x <tt>opus_int32</tt>: Input precision in bits, between 8 and 24 |
| | | * (default: 24). |
| | | * @hideinitializer */ |
| | | #define OPUS_SET_LSB_DEPTH(x) OPUS_SET_LSB_DEPTH_REQUEST, __opus_check_int(x) |
| | | /** Gets the encoder's configured signal depth. |
| | | * @see OPUS_SET_LSB_DEPTH |
| | | * @param[out] x <tt>opus_int32 *</tt>: Input precision in bits, between 8 and |
| | | * 24 (default: 24). |
| | | * @hideinitializer */ |
| | | #define OPUS_GET_LSB_DEPTH(x) OPUS_GET_LSB_DEPTH_REQUEST, __opus_check_int_ptr(x) |
| | | |
| | | /** Configures the encoder's use of variable duration frames. |
| | | * When variable duration is enabled, the encoder is free to use a shorter frame |
| | | * size than the one requested in the opus_encode*() call. |
| | | * It is then the user's responsibility |
| | | * to verify how much audio was encoded by checking the ToC byte of the encoded |
| | | * packet. The part of the audio that was not encoded needs to be resent to the |
| | | * encoder for the next call. Do not use this option unless you <b>really</b> |
| | | * know what you are doing. |
| | | * @see OPUS_GET_EXPERT_FRAME_DURATION |
| | | * @param[in] x <tt>opus_int32</tt>: Allowed values: |
| | | * <dl> |
| | | * <dt>OPUS_FRAMESIZE_ARG</dt><dd>Select frame size from the argument (default).</dd> |
| | | * <dt>OPUS_FRAMESIZE_2_5_MS</dt><dd>Use 2.5 ms frames.</dd> |
| | | * <dt>OPUS_FRAMESIZE_5_MS</dt><dd>Use 5 ms frames.</dd> |
| | | * <dt>OPUS_FRAMESIZE_10_MS</dt><dd>Use 10 ms frames.</dd> |
| | | * <dt>OPUS_FRAMESIZE_20_MS</dt><dd>Use 20 ms frames.</dd> |
| | | * <dt>OPUS_FRAMESIZE_40_MS</dt><dd>Use 40 ms frames.</dd> |
| | | * <dt>OPUS_FRAMESIZE_60_MS</dt><dd>Use 60 ms frames.</dd> |
| | | * <dt>OPUS_FRAMESIZE_VARIABLE</dt><dd>Optimize the frame size dynamically.</dd> |
| | | * </dl> |
| | | * @hideinitializer */ |
| | | #define OPUS_SET_EXPERT_FRAME_DURATION(x) OPUS_SET_EXPERT_FRAME_DURATION_REQUEST, __opus_check_int(x) |
| | | /** Gets the encoder's configured use of variable duration frames. |
| | | * @see OPUS_SET_EXPERT_FRAME_DURATION |
| | | * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values: |
| | | * <dl> |
| | | * <dt>OPUS_FRAMESIZE_ARG</dt><dd>Select frame size from the argument (default).</dd> |
| | | * <dt>OPUS_FRAMESIZE_2_5_MS</dt><dd>Use 2.5 ms frames.</dd> |
| | | * <dt>OPUS_FRAMESIZE_5_MS</dt><dd>Use 5 ms frames.</dd> |
| | | * <dt>OPUS_FRAMESIZE_10_MS</dt><dd>Use 10 ms frames.</dd> |
| | | * <dt>OPUS_FRAMESIZE_20_MS</dt><dd>Use 20 ms frames.</dd> |
| | | * <dt>OPUS_FRAMESIZE_40_MS</dt><dd>Use 40 ms frames.</dd> |
| | | * <dt>OPUS_FRAMESIZE_60_MS</dt><dd>Use 60 ms frames.</dd> |
| | | * <dt>OPUS_FRAMESIZE_VARIABLE</dt><dd>Optimize the frame size dynamically.</dd> |
| | | * </dl> |
| | | * @hideinitializer */ |
| | | #define OPUS_GET_EXPERT_FRAME_DURATION(x) OPUS_GET_EXPERT_FRAME_DURATION_REQUEST, __opus_check_int_ptr(x) |
| | | |
| | | /** If set to 1, disables almost all use of prediction, making frames almost |
| | | * completely independent. This reduces quality. |
| | | * @see OPUS_GET_PREDICTION_DISABLED |
| | | * @param[in] x <tt>opus_int32</tt>: Allowed values: |
| | | * <dl> |
| | | * <dt>0</dt><dd>Enable prediction (default).</dd> |
| | | * <dt>1</dt><dd>Disable prediction.</dd> |
| | | * </dl> |
| | | * @hideinitializer */ |
| | | #define OPUS_SET_PREDICTION_DISABLED(x) OPUS_SET_PREDICTION_DISABLED_REQUEST, __opus_check_int(x) |
| | | /** Gets the encoder's configured prediction status. |
| | | * @see OPUS_SET_PREDICTION_DISABLED |
| | | * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values: |
| | | * <dl> |
| | | * <dt>0</dt><dd>Prediction enabled (default).</dd> |
| | | * <dt>1</dt><dd>Prediction disabled.</dd> |
| | | * </dl> |
| | | * @hideinitializer */ |
| | | #define OPUS_GET_PREDICTION_DISABLED(x) OPUS_GET_PREDICTION_DISABLED_REQUEST, __opus_check_int_ptr(x) |
| | | |
| | | /**@}*/ |
| | | |
| | | /** @defgroup opus_genericctls Generic CTLs |
| | | * |
| | | * These macros are used with the \c opus_decoder_ctl and |
| | | * \c opus_encoder_ctl calls to generate a particular |
| | | * request. |
| | | * |
| | | * When called on an \c OpusDecoder they apply to that |
| | | * particular decoder instance. When called on an |
| | | * \c OpusEncoder they apply to the corresponding setting |
| | | * on that encoder instance, if present. |
| | | * |
| | | * Some usage examples: |
| | | * |
| | | * @code |
| | | * int ret; |
| | | * opus_int32 pitch; |
| | | * ret = opus_decoder_ctl(dec_ctx, OPUS_GET_PITCH(&pitch)); |
| | | * if (ret == OPUS_OK) return ret; |
| | | * |
| | | * opus_encoder_ctl(enc_ctx, OPUS_RESET_STATE); |
| | | * opus_decoder_ctl(dec_ctx, OPUS_RESET_STATE); |
| | | * |
| | | * opus_int32 enc_bw, dec_bw; |
| | | * opus_encoder_ctl(enc_ctx, OPUS_GET_BANDWIDTH(&enc_bw)); |
| | | * opus_decoder_ctl(dec_ctx, OPUS_GET_BANDWIDTH(&dec_bw)); |
| | | * if (enc_bw != dec_bw) { |
| | | * printf("packet bandwidth mismatch!\n"); |
| | | * } |
| | | * @endcode |
| | | * |
| | | * @see opus_encoder, opus_decoder_ctl, opus_encoder_ctl, opus_decoderctls, opus_encoderctls |
| | | * @{ |
| | | */ |
| | | |
| | | /** Resets the codec state to be equivalent to a freshly initialized state. |
| | | * This should be called when switching streams in order to prevent |
| | | * the back to back decoding from giving different results from |
| | | * one at a time decoding. |
| | | * @hideinitializer */ |
| | | #define OPUS_RESET_STATE 4028 |
| | | |
| | | /** Gets the final state of the codec's entropy coder. |
| | | * This is used for testing purposes, |
| | | * The encoder and decoder state should be identical after coding a payload |
| | | * (assuming no data corruption or software bugs) |
| | | * |
| | | * @param[out] x <tt>opus_uint32 *</tt>: Entropy coder state |
| | | * |
| | | * @hideinitializer */ |
| | | #define OPUS_GET_FINAL_RANGE(x) OPUS_GET_FINAL_RANGE_REQUEST, __opus_check_uint_ptr(x) |
| | | |
| | | /** Gets the encoder's configured bandpass or the decoder's last bandpass. |
| | | * @see OPUS_SET_BANDWIDTH |
| | | * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values: |
| | | * <dl> |
| | | * <dt>#OPUS_AUTO</dt> <dd>(default)</dd> |
| | | * <dt>#OPUS_BANDWIDTH_NARROWBAND</dt> <dd>4 kHz passband</dd> |
| | | * <dt>#OPUS_BANDWIDTH_MEDIUMBAND</dt> <dd>6 kHz passband</dd> |
| | | * <dt>#OPUS_BANDWIDTH_WIDEBAND</dt> <dd>8 kHz passband</dd> |
| | | * <dt>#OPUS_BANDWIDTH_SUPERWIDEBAND</dt><dd>12 kHz passband</dd> |
| | | * <dt>#OPUS_BANDWIDTH_FULLBAND</dt> <dd>20 kHz passband</dd> |
| | | * </dl> |
| | | * @hideinitializer */ |
| | | #define OPUS_GET_BANDWIDTH(x) OPUS_GET_BANDWIDTH_REQUEST, __opus_check_int_ptr(x) |
| | | |
| | | /** Gets the sampling rate the encoder or decoder was initialized with. |
| | | * This simply returns the <code>Fs</code> value passed to opus_encoder_init() |
| | | * or opus_decoder_init(). |
| | | * @param[out] x <tt>opus_int32 *</tt>: Sampling rate of encoder or decoder. |
| | | * @hideinitializer |
| | | */ |
| | | #define OPUS_GET_SAMPLE_RATE(x) OPUS_GET_SAMPLE_RATE_REQUEST, __opus_check_int_ptr(x) |
| | | |
| | | /**@}*/ |
| | | |
| | | /** @defgroup opus_decoderctls Decoder related CTLs |
| | | * @see opus_genericctls, opus_encoderctls, opus_decoder |
| | | * @{ |
| | | */ |
| | | |
| | | /** Configures decoder gain adjustment. |
| | | * Scales the decoded output by a factor specified in Q8 dB units. |
| | | * This has a maximum range of -32768 to 32767 inclusive, and returns |
| | | * OPUS_BAD_ARG otherwise. The default is zero indicating no adjustment. |
| | | * This setting survives decoder reset. |
| | | * |
| | | * gain = pow(10, x/(20.0*256)) |
| | | * |
| | | * @param[in] x <tt>opus_int32</tt>: Amount to scale PCM signal by in Q8 dB units. |
| | | * @hideinitializer */ |
| | | #define OPUS_SET_GAIN(x) OPUS_SET_GAIN_REQUEST, __opus_check_int(x) |
| | | /** Gets the decoder's configured gain adjustment. @see OPUS_SET_GAIN |
| | | * |
| | | * @param[out] x <tt>opus_int32 *</tt>: Amount to scale PCM signal by in Q8 dB units. |
| | | * @hideinitializer */ |
| | | #define OPUS_GET_GAIN(x) OPUS_GET_GAIN_REQUEST, __opus_check_int_ptr(x) |
| | | |
| | | /** Gets the duration (in samples) of the last packet successfully decoded or concealed. |
| | | * @param[out] x <tt>opus_int32 *</tt>: Number of samples (at current sampling rate). |
| | | * @hideinitializer */ |
| | | #define OPUS_GET_LAST_PACKET_DURATION(x) OPUS_GET_LAST_PACKET_DURATION_REQUEST, __opus_check_int_ptr(x) |
| | | |
| | | /** Gets the pitch of the last decoded frame, if available. |
| | | * This can be used for any post-processing algorithm requiring the use of pitch, |
| | | * e.g. time stretching/shortening. If the last frame was not voiced, or if the |
| | | * pitch was not coded in the frame, then zero is returned. |
| | | * |
| | | * This CTL is only implemented for decoder instances. |
| | | * |
| | | * @param[out] x <tt>opus_int32 *</tt>: pitch period at 48 kHz (or 0 if not available) |
| | | * |
| | | * @hideinitializer */ |
| | | #define OPUS_GET_PITCH(x) OPUS_GET_PITCH_REQUEST, __opus_check_int_ptr(x) |
| | | |
| | | /**@}*/ |
| | | |
| | | /** @defgroup opus_libinfo Opus library information functions |
| | | * @{ |
| | | */ |
| | | |
| | | /** Converts an opus error code into a human readable string. |
| | | * |
| | | * @param[in] error <tt>int</tt>: Error number |
| | | * @returns Error string |
| | | */ |
| | | OPUS_EXPORT const char *opus_strerror(int error); |
| | | |
| | | /** Gets the libopus version string. |
| | | * |
| | | * Applications may look for the substring "-fixed" in the version string to |
| | | * determine whether they have a fixed-point or floating-point build at |
| | | * runtime. |
| | | * |
| | | * @returns Version string |
| | | */ |
| | | OPUS_EXPORT const char *opus_get_version_string(void); |
| | | /**@}*/ |
| | | |
| | | #ifdef __cplusplus |
| | | } |
| | | #endif |
| | | |
| | | #endif /* OPUS_DEFINES_H */ |
New file |
| | |
| | | /* Copyright (c) 2011 Xiph.Org Foundation |
| | | Written by Jean-Marc Valin */ |
| | | /* |
| | | 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. |
| | | |
| | | 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. |
| | | */ |
| | | |
| | | /** |
| | | * @file opus_multistream.h |
| | | * @brief Opus reference implementation multistream API |
| | | */ |
| | | |
| | | #ifndef OPUS_MULTISTREAM_H |
| | | #define OPUS_MULTISTREAM_H |
| | | |
| | | #include "opus.h" |
| | | |
| | | #ifdef __cplusplus |
| | | extern "C" { |
| | | #endif |
| | | |
| | | /** @cond OPUS_INTERNAL_DOC */ |
| | | |
| | | /** Macros to trigger compilation errors when the wrong types are provided to a |
| | | * CTL. */ |
| | | /**@{*/ |
| | | #define __opus_check_encstate_ptr(ptr) ((ptr) + ((ptr) - (OpusEncoder**)(ptr))) |
| | | #define __opus_check_decstate_ptr(ptr) ((ptr) + ((ptr) - (OpusDecoder**)(ptr))) |
| | | /**@}*/ |
| | | |
| | | /** These are the actual encoder and decoder CTL ID numbers. |
| | | * They should not be used directly by applications. |
| | | * In general, SETs should be even and GETs should be odd.*/ |
| | | /**@{*/ |
| | | #define OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST 5120 |
| | | #define OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST 5122 |
| | | /**@}*/ |
| | | |
| | | /** @endcond */ |
| | | |
| | | /** @defgroup opus_multistream_ctls Multistream specific encoder and decoder CTLs |
| | | * |
| | | * These are convenience macros that are specific to the |
| | | * opus_multistream_encoder_ctl() and opus_multistream_decoder_ctl() |
| | | * interface. |
| | | * The CTLs from @ref opus_genericctls, @ref opus_encoderctls, and |
| | | * @ref opus_decoderctls may be applied to a multistream encoder or decoder as |
| | | * well. |
| | | * In addition, you may retrieve the encoder or decoder state for an specific |
| | | * stream via #OPUS_MULTISTREAM_GET_ENCODER_STATE or |
| | | * #OPUS_MULTISTREAM_GET_DECODER_STATE and apply CTLs to it individually. |
| | | */ |
| | | /**@{*/ |
| | | |
| | | /** Gets the encoder state for an individual stream of a multistream encoder. |
| | | * @param[in] x <tt>opus_int32</tt>: The index of the stream whose encoder you |
| | | * wish to retrieve. |
| | | * This must be non-negative and less than |
| | | * the <code>streams</code> parameter used |
| | | * to initialize the encoder. |
| | | * @param[out] y <tt>OpusEncoder**</tt>: Returns a pointer to the given |
| | | * encoder state. |
| | | * @retval OPUS_BAD_ARG The index of the requested stream was out of range. |
| | | * @hideinitializer |
| | | */ |
| | | #define OPUS_MULTISTREAM_GET_ENCODER_STATE(x,y) OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST, __opus_check_int(x), __opus_check_encstate_ptr(y) |
| | | |
| | | /** Gets the decoder state for an individual stream of a multistream decoder. |
| | | * @param[in] x <tt>opus_int32</tt>: The index of the stream whose decoder you |
| | | * wish to retrieve. |
| | | * This must be non-negative and less than |
| | | * the <code>streams</code> parameter used |
| | | * to initialize the decoder. |
| | | * @param[out] y <tt>OpusDecoder**</tt>: Returns a pointer to the given |
| | | * decoder state. |
| | | * @retval OPUS_BAD_ARG The index of the requested stream was out of range. |
| | | * @hideinitializer |
| | | */ |
| | | #define OPUS_MULTISTREAM_GET_DECODER_STATE(x,y) OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST, __opus_check_int(x), __opus_check_decstate_ptr(y) |
| | | |
| | | /**@}*/ |
| | | |
| | | /** @defgroup opus_multistream Opus Multistream API |
| | | * @{ |
| | | * |
| | | * The multistream API allows individual Opus streams to be combined into a |
| | | * single packet, enabling support for up to 255 channels. Unlike an |
| | | * elementary Opus stream, the encoder and decoder must negotiate the channel |
| | | * configuration before the decoder can successfully interpret the data in the |
| | | * packets produced by the encoder. Some basic information, such as packet |
| | | * duration, can be computed without any special negotiation. |
| | | * |
| | | * The format for multistream Opus packets is defined in |
| | | * <a href="https://tools.ietf.org/html/rfc7845">RFC 7845</a> |
| | | * and is based on the self-delimited Opus framing described in Appendix B of |
| | | * <a href="https://tools.ietf.org/html/rfc6716">RFC 6716</a>. |
| | | * Normal Opus packets are just a degenerate case of multistream Opus packets, |
| | | * and can be encoded or decoded with the multistream API by setting |
| | | * <code>streams</code> to <code>1</code> when initializing the encoder or |
| | | * decoder. |
| | | * |
| | | * Multistream Opus streams can contain up to 255 elementary Opus streams. |
| | | * These may be either "uncoupled" or "coupled", indicating that the decoder |
| | | * is configured to decode them to either 1 or 2 channels, respectively. |
| | | * The streams are ordered so that all coupled streams appear at the |
| | | * beginning. |
| | | * |
| | | * A <code>mapping</code> table defines which decoded channel <code>i</code> |
| | | * should be used for each input/output (I/O) channel <code>j</code>. This table is |
| | | * typically provided as an unsigned char array. |
| | | * Let <code>i = mapping[j]</code> be the index for I/O channel <code>j</code>. |
| | | * If <code>i < 2*coupled_streams</code>, then I/O channel <code>j</code> is |
| | | * encoded as the left channel of stream <code>(i/2)</code> if <code>i</code> |
| | | * is even, or as the right channel of stream <code>(i/2)</code> if |
| | | * <code>i</code> is odd. Otherwise, I/O channel <code>j</code> is encoded as |
| | | * mono in stream <code>(i - coupled_streams)</code>, unless it has the special |
| | | * value 255, in which case it is omitted from the encoding entirely (the |
| | | * decoder will reproduce it as silence). Each value <code>i</code> must either |
| | | * be the special value 255 or be less than <code>streams + coupled_streams</code>. |
| | | * |
| | | * The output channels specified by the encoder |
| | | * should use the |
| | | * <a href="https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-810004.3.9">Vorbis |
| | | * channel ordering</a>. A decoder may wish to apply an additional permutation |
| | | * to the mapping the encoder used to achieve a different output channel |
| | | * order (e.g. for outputing in WAV order). |
| | | * |
| | | * Each multistream packet contains an Opus packet for each stream, and all of |
| | | * the Opus packets in a single multistream packet must have the same |
| | | * duration. Therefore the duration of a multistream packet can be extracted |
| | | * from the TOC sequence of the first stream, which is located at the |
| | | * beginning of the packet, just like an elementary Opus stream: |
| | | * |
| | | * @code |
| | | * int nb_samples; |
| | | * int nb_frames; |
| | | * nb_frames = opus_packet_get_nb_frames(data, len); |
| | | * if (nb_frames < 1) |
| | | * return nb_frames; |
| | | * nb_samples = opus_packet_get_samples_per_frame(data, 48000) * nb_frames; |
| | | * @endcode |
| | | * |
| | | * The general encoding and decoding process proceeds exactly the same as in |
| | | * the normal @ref opus_encoder and @ref opus_decoder APIs. |
| | | * See their documentation for an overview of how to use the corresponding |
| | | * multistream functions. |
| | | */ |
| | | |
| | | /** Opus multistream encoder state. |
| | | * This contains the complete state of a multistream Opus encoder. |
| | | * It is position independent and can be freely copied. |
| | | * @see opus_multistream_encoder_create |
| | | * @see opus_multistream_encoder_init |
| | | */ |
| | | typedef struct OpusMSEncoder OpusMSEncoder; |
| | | |
| | | /** Opus multistream decoder state. |
| | | * This contains the complete state of a multistream Opus decoder. |
| | | * It is position independent and can be freely copied. |
| | | * @see opus_multistream_decoder_create |
| | | * @see opus_multistream_decoder_init |
| | | */ |
| | | typedef struct OpusMSDecoder OpusMSDecoder; |
| | | |
| | | /**\name Multistream encoder functions */ |
| | | /**@{*/ |
| | | |
| | | /** Gets the size of an OpusMSEncoder structure. |
| | | * @param streams <tt>int</tt>: The total number of streams to encode from the |
| | | * input. |
| | | * This must be no more than 255. |
| | | * @param coupled_streams <tt>int</tt>: Number of coupled (2 channel) streams |
| | | * to encode. |
| | | * This must be no larger than the total |
| | | * number of streams. |
| | | * Additionally, The total number of |
| | | * encoded channels (<code>streams + |
| | | * coupled_streams</code>) must be no |
| | | * more than 255. |
| | | * @returns The size in bytes on success, or a negative error code |
| | | * (see @ref opus_errorcodes) on error. |
| | | */ |
| | | OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_encoder_get_size( |
| | | int streams, |
| | | int coupled_streams |
| | | ); |
| | | |
| | | OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_surround_encoder_get_size( |
| | | int channels, |
| | | int mapping_family |
| | | ); |
| | | |
| | | |
| | | /** Allocates and initializes a multistream encoder state. |
| | | * Call opus_multistream_encoder_destroy() to release |
| | | * this object when finished. |
| | | * @param Fs <tt>opus_int32</tt>: Sampling rate of the input signal (in Hz). |
| | | * This must be one of 8000, 12000, 16000, |
| | | * 24000, or 48000. |
| | | * @param channels <tt>int</tt>: Number of channels in the input signal. |
| | | * This must be at most 255. |
| | | * It may be greater than the number of |
| | | * coded channels (<code>streams + |
| | | * coupled_streams</code>). |
| | | * @param streams <tt>int</tt>: The total number of streams to encode from the |
| | | * input. |
| | | * This must be no more than the number of channels. |
| | | * @param coupled_streams <tt>int</tt>: Number of coupled (2 channel) streams |
| | | * to encode. |
| | | * This must be no larger than the total |
| | | * number of streams. |
| | | * Additionally, The total number of |
| | | * encoded channels (<code>streams + |
| | | * coupled_streams</code>) must be no |
| | | * more than the number of input channels. |
| | | * @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from |
| | | * encoded channels to input channels, as described in |
| | | * @ref opus_multistream. As an extra constraint, the |
| | | * multistream encoder does not allow encoding coupled |
| | | * streams for which one channel is unused since this |
| | | * is never a good idea. |
| | | * @param application <tt>int</tt>: The target encoder application. |
| | | * This must be one of the following: |
| | | * <dl> |
| | | * <dt>#OPUS_APPLICATION_VOIP</dt> |
| | | * <dd>Process signal for improved speech intelligibility.</dd> |
| | | * <dt>#OPUS_APPLICATION_AUDIO</dt> |
| | | * <dd>Favor faithfulness to the original input.</dd> |
| | | * <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt> |
| | | * <dd>Configure the minimum possible coding delay by disabling certain modes |
| | | * of operation.</dd> |
| | | * </dl> |
| | | * @param[out] error <tt>int *</tt>: Returns #OPUS_OK on success, or an error |
| | | * code (see @ref opus_errorcodes) on |
| | | * failure. |
| | | */ |
| | | OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSEncoder *opus_multistream_encoder_create( |
| | | opus_int32 Fs, |
| | | int channels, |
| | | int streams, |
| | | int coupled_streams, |
| | | const unsigned char *mapping, |
| | | int application, |
| | | int *error |
| | | ) OPUS_ARG_NONNULL(5); |
| | | |
| | | OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSEncoder *opus_multistream_surround_encoder_create( |
| | | opus_int32 Fs, |
| | | int channels, |
| | | int mapping_family, |
| | | int *streams, |
| | | int *coupled_streams, |
| | | unsigned char *mapping, |
| | | int application, |
| | | int *error |
| | | ) OPUS_ARG_NONNULL(5); |
| | | |
| | | /** Initialize a previously allocated multistream encoder state. |
| | | * The memory pointed to by \a st must be at least the size returned by |
| | | * opus_multistream_encoder_get_size(). |
| | | * This is intended for applications which use their own allocator instead of |
| | | * malloc. |
| | | * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. |
| | | * @see opus_multistream_encoder_create |
| | | * @see opus_multistream_encoder_get_size |
| | | * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state to initialize. |
| | | * @param Fs <tt>opus_int32</tt>: Sampling rate of the input signal (in Hz). |
| | | * This must be one of 8000, 12000, 16000, |
| | | * 24000, or 48000. |
| | | * @param channels <tt>int</tt>: Number of channels in the input signal. |
| | | * This must be at most 255. |
| | | * It may be greater than the number of |
| | | * coded channels (<code>streams + |
| | | * coupled_streams</code>). |
| | | * @param streams <tt>int</tt>: The total number of streams to encode from the |
| | | * input. |
| | | * This must be no more than the number of channels. |
| | | * @param coupled_streams <tt>int</tt>: Number of coupled (2 channel) streams |
| | | * to encode. |
| | | * This must be no larger than the total |
| | | * number of streams. |
| | | * Additionally, The total number of |
| | | * encoded channels (<code>streams + |
| | | * coupled_streams</code>) must be no |
| | | * more than the number of input channels. |
| | | * @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from |
| | | * encoded channels to input channels, as described in |
| | | * @ref opus_multistream. As an extra constraint, the |
| | | * multistream encoder does not allow encoding coupled |
| | | * streams for which one channel is unused since this |
| | | * is never a good idea. |
| | | * @param application <tt>int</tt>: The target encoder application. |
| | | * This must be one of the following: |
| | | * <dl> |
| | | * <dt>#OPUS_APPLICATION_VOIP</dt> |
| | | * <dd>Process signal for improved speech intelligibility.</dd> |
| | | * <dt>#OPUS_APPLICATION_AUDIO</dt> |
| | | * <dd>Favor faithfulness to the original input.</dd> |
| | | * <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt> |
| | | * <dd>Configure the minimum possible coding delay by disabling certain modes |
| | | * of operation.</dd> |
| | | * </dl> |
| | | * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes) |
| | | * on failure. |
| | | */ |
| | | OPUS_EXPORT int opus_multistream_encoder_init( |
| | | OpusMSEncoder *st, |
| | | opus_int32 Fs, |
| | | int channels, |
| | | int streams, |
| | | int coupled_streams, |
| | | const unsigned char *mapping, |
| | | int application |
| | | ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6); |
| | | |
| | | OPUS_EXPORT int opus_multistream_surround_encoder_init( |
| | | OpusMSEncoder *st, |
| | | opus_int32 Fs, |
| | | int channels, |
| | | int mapping_family, |
| | | int *streams, |
| | | int *coupled_streams, |
| | | unsigned char *mapping, |
| | | int application |
| | | ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6); |
| | | |
| | | /** Encodes a multistream Opus frame. |
| | | * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state. |
| | | * @param[in] pcm <tt>const opus_int16*</tt>: The input signal as interleaved |
| | | * samples. |
| | | * This must contain |
| | | * <code>frame_size*channels</code> |
| | | * samples. |
| | | * @param frame_size <tt>int</tt>: Number of samples per channel in the input |
| | | * signal. |
| | | * This must be an Opus frame size for the |
| | | * encoder's sampling rate. |
| | | * For example, at 48 kHz the permitted values |
| | | * are 120, 240, 480, 960, 1920, and 2880. |
| | | * Passing in a duration of less than 10 ms |
| | | * (480 samples at 48 kHz) will prevent the |
| | | * encoder from using the LPC or hybrid modes. |
| | | * @param[out] data <tt>unsigned char*</tt>: Output payload. |
| | | * This must contain storage for at |
| | | * least \a max_data_bytes. |
| | | * @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated |
| | | * memory for the output |
| | | * payload. This may be |
| | | * used to impose an upper limit on |
| | | * the instant bitrate, but should |
| | | * not be used as the only bitrate |
| | | * control. Use #OPUS_SET_BITRATE to |
| | | * control the bitrate. |
| | | * @returns The length of the encoded packet (in bytes) on success or a |
| | | * negative error code (see @ref opus_errorcodes) on failure. |
| | | */ |
| | | OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode( |
| | | OpusMSEncoder *st, |
| | | const opus_int16 *pcm, |
| | | int frame_size, |
| | | unsigned char *data, |
| | | opus_int32 max_data_bytes |
| | | ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); |
| | | |
| | | /** Encodes a multistream Opus frame from floating point input. |
| | | * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state. |
| | | * @param[in] pcm <tt>const float*</tt>: The input signal as interleaved |
| | | * samples with a normal range of |
| | | * +/-1.0. |
| | | * Samples with a range beyond +/-1.0 |
| | | * are supported but will be clipped by |
| | | * decoders using the integer API and |
| | | * should only be used if it is known |
| | | * that the far end supports extended |
| | | * dynamic range. |
| | | * This must contain |
| | | * <code>frame_size*channels</code> |
| | | * samples. |
| | | * @param frame_size <tt>int</tt>: Number of samples per channel in the input |
| | | * signal. |
| | | * This must be an Opus frame size for the |
| | | * encoder's sampling rate. |
| | | * For example, at 48 kHz the permitted values |
| | | * are 120, 240, 480, 960, 1920, and 2880. |
| | | * Passing in a duration of less than 10 ms |
| | | * (480 samples at 48 kHz) will prevent the |
| | | * encoder from using the LPC or hybrid modes. |
| | | * @param[out] data <tt>unsigned char*</tt>: Output payload. |
| | | * This must contain storage for at |
| | | * least \a max_data_bytes. |
| | | * @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated |
| | | * memory for the output |
| | | * payload. This may be |
| | | * used to impose an upper limit on |
| | | * the instant bitrate, but should |
| | | * not be used as the only bitrate |
| | | * control. Use #OPUS_SET_BITRATE to |
| | | * control the bitrate. |
| | | * @returns The length of the encoded packet (in bytes) on success or a |
| | | * negative error code (see @ref opus_errorcodes) on failure. |
| | | */ |
| | | OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode_float( |
| | | OpusMSEncoder *st, |
| | | const float *pcm, |
| | | int frame_size, |
| | | unsigned char *data, |
| | | opus_int32 max_data_bytes |
| | | ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); |
| | | |
| | | /** Frees an <code>OpusMSEncoder</code> allocated by |
| | | * opus_multistream_encoder_create(). |
| | | * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state to be freed. |
| | | */ |
| | | OPUS_EXPORT void opus_multistream_encoder_destroy(OpusMSEncoder *st); |
| | | |
| | | /** Perform a CTL function on a multistream Opus encoder. |
| | | * |
| | | * Generally the request and subsequent arguments are generated by a |
| | | * convenience macro. |
| | | * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state. |
| | | * @param request This and all remaining parameters should be replaced by one |
| | | * of the convenience macros in @ref opus_genericctls, |
| | | * @ref opus_encoderctls, or @ref opus_multistream_ctls. |
| | | * @see opus_genericctls |
| | | * @see opus_encoderctls |
| | | * @see opus_multistream_ctls |
| | | */ |
| | | OPUS_EXPORT int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...) OPUS_ARG_NONNULL(1); |
| | | |
| | | /**@}*/ |
| | | |
| | | /**\name Multistream decoder functions */ |
| | | /**@{*/ |
| | | |
| | | /** Gets the size of an <code>OpusMSDecoder</code> structure. |
| | | * @param streams <tt>int</tt>: The total number of streams coded in the |
| | | * input. |
| | | * This must be no more than 255. |
| | | * @param coupled_streams <tt>int</tt>: Number streams to decode as coupled |
| | | * (2 channel) streams. |
| | | * This must be no larger than the total |
| | | * number of streams. |
| | | * Additionally, The total number of |
| | | * coded channels (<code>streams + |
| | | * coupled_streams</code>) must be no |
| | | * more than 255. |
| | | * @returns The size in bytes on success, or a negative error code |
| | | * (see @ref opus_errorcodes) on error. |
| | | */ |
| | | OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_decoder_get_size( |
| | | int streams, |
| | | int coupled_streams |
| | | ); |
| | | |
| | | /** Allocates and initializes a multistream decoder state. |
| | | * Call opus_multistream_decoder_destroy() to release |
| | | * this object when finished. |
| | | * @param Fs <tt>opus_int32</tt>: Sampling rate to decode at (in Hz). |
| | | * This must be one of 8000, 12000, 16000, |
| | | * 24000, or 48000. |
| | | * @param channels <tt>int</tt>: Number of channels to output. |
| | | * This must be at most 255. |
| | | * It may be different from the number of coded |
| | | * channels (<code>streams + |
| | | * coupled_streams</code>). |
| | | * @param streams <tt>int</tt>: The total number of streams coded in the |
| | | * input. |
| | | * This must be no more than 255. |
| | | * @param coupled_streams <tt>int</tt>: Number of streams to decode as coupled |
| | | * (2 channel) streams. |
| | | * This must be no larger than the total |
| | | * number of streams. |
| | | * Additionally, The total number of |
| | | * coded channels (<code>streams + |
| | | * coupled_streams</code>) must be no |
| | | * more than 255. |
| | | * @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from |
| | | * coded channels to output channels, as described in |
| | | * @ref opus_multistream. |
| | | * @param[out] error <tt>int *</tt>: Returns #OPUS_OK on success, or an error |
| | | * code (see @ref opus_errorcodes) on |
| | | * failure. |
| | | */ |
| | | OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSDecoder *opus_multistream_decoder_create( |
| | | opus_int32 Fs, |
| | | int channels, |
| | | int streams, |
| | | int coupled_streams, |
| | | const unsigned char *mapping, |
| | | int *error |
| | | ) OPUS_ARG_NONNULL(5); |
| | | |
| | | /** Intialize a previously allocated decoder state object. |
| | | * The memory pointed to by \a st must be at least the size returned by |
| | | * opus_multistream_encoder_get_size(). |
| | | * This is intended for applications which use their own allocator instead of |
| | | * malloc. |
| | | * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. |
| | | * @see opus_multistream_decoder_create |
| | | * @see opus_multistream_deocder_get_size |
| | | * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state to initialize. |
| | | * @param Fs <tt>opus_int32</tt>: Sampling rate to decode at (in Hz). |
| | | * This must be one of 8000, 12000, 16000, |
| | | * 24000, or 48000. |
| | | * @param channels <tt>int</tt>: Number of channels to output. |
| | | * This must be at most 255. |
| | | * It may be different from the number of coded |
| | | * channels (<code>streams + |
| | | * coupled_streams</code>). |
| | | * @param streams <tt>int</tt>: The total number of streams coded in the |
| | | * input. |
| | | * This must be no more than 255. |
| | | * @param coupled_streams <tt>int</tt>: Number of streams to decode as coupled |
| | | * (2 channel) streams. |
| | | * This must be no larger than the total |
| | | * number of streams. |
| | | * Additionally, The total number of |
| | | * coded channels (<code>streams + |
| | | * coupled_streams</code>) must be no |
| | | * more than 255. |
| | | * @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from |
| | | * coded channels to output channels, as described in |
| | | * @ref opus_multistream. |
| | | * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes) |
| | | * on failure. |
| | | */ |
| | | OPUS_EXPORT int opus_multistream_decoder_init( |
| | | OpusMSDecoder *st, |
| | | opus_int32 Fs, |
| | | int channels, |
| | | int streams, |
| | | int coupled_streams, |
| | | const unsigned char *mapping |
| | | ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6); |
| | | |
| | | /** Decode a multistream Opus packet. |
| | | * @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state. |
| | | * @param[in] data <tt>const unsigned char*</tt>: Input payload. |
| | | * Use a <code>NULL</code> |
| | | * pointer to indicate packet |
| | | * loss. |
| | | * @param len <tt>opus_int32</tt>: Number of bytes in payload. |
| | | * @param[out] pcm <tt>opus_int16*</tt>: Output signal, with interleaved |
| | | * samples. |
| | | * This must contain room for |
| | | * <code>frame_size*channels</code> |
| | | * samples. |
| | | * @param frame_size <tt>int</tt>: The number of samples per channel of |
| | | * available space in \a pcm. |
| | | * If this is less than the maximum packet duration |
| | | * (120 ms; 5760 for 48kHz), this function will not be capable |
| | | * of decoding some packets. In the case of PLC (data==NULL) |
| | | * or FEC (decode_fec=1), then frame_size needs to be exactly |
| | | * the duration of audio that is missing, otherwise the |
| | | * decoder will not be in the optimal state to decode the |
| | | * next incoming packet. For the PLC and FEC cases, frame_size |
| | | * <b>must</b> be a multiple of 2.5 ms. |
| | | * @param decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band |
| | | * forward error correction data be decoded. |
| | | * If no such data is available, the frame is |
| | | * decoded as if it were lost. |
| | | * @returns Number of samples decoded on success or a negative error code |
| | | * (see @ref opus_errorcodes) on failure. |
| | | */ |
| | | OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode( |
| | | OpusMSDecoder *st, |
| | | const unsigned char *data, |
| | | opus_int32 len, |
| | | opus_int16 *pcm, |
| | | int frame_size, |
| | | int decode_fec |
| | | ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); |
| | | |
| | | /** Decode a multistream Opus packet with floating point output. |
| | | * @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state. |
| | | * @param[in] data <tt>const unsigned char*</tt>: Input payload. |
| | | * Use a <code>NULL</code> |
| | | * pointer to indicate packet |
| | | * loss. |
| | | * @param len <tt>opus_int32</tt>: Number of bytes in payload. |
| | | * @param[out] pcm <tt>opus_int16*</tt>: Output signal, with interleaved |
| | | * samples. |
| | | * This must contain room for |
| | | * <code>frame_size*channels</code> |
| | | * samples. |
| | | * @param frame_size <tt>int</tt>: The number of samples per channel of |
| | | * available space in \a pcm. |
| | | * If this is less than the maximum packet duration |
| | | * (120 ms; 5760 for 48kHz), this function will not be capable |
| | | * of decoding some packets. In the case of PLC (data==NULL) |
| | | * or FEC (decode_fec=1), then frame_size needs to be exactly |
| | | * the duration of audio that is missing, otherwise the |
| | | * decoder will not be in the optimal state to decode the |
| | | * next incoming packet. For the PLC and FEC cases, frame_size |
| | | * <b>must</b> be a multiple of 2.5 ms. |
| | | * @param decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band |
| | | * forward error correction data be decoded. |
| | | * If no such data is available, the frame is |
| | | * decoded as if it were lost. |
| | | * @returns Number of samples decoded on success or a negative error code |
| | | * (see @ref opus_errorcodes) on failure. |
| | | */ |
| | | OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode_float( |
| | | OpusMSDecoder *st, |
| | | const unsigned char *data, |
| | | opus_int32 len, |
| | | float *pcm, |
| | | int frame_size, |
| | | int decode_fec |
| | | ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); |
| | | |
| | | /** Perform a CTL function on a multistream Opus decoder. |
| | | * |
| | | * Generally the request and subsequent arguments are generated by a |
| | | * convenience macro. |
| | | * @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state. |
| | | * @param request This and all remaining parameters should be replaced by one |
| | | * of the convenience macros in @ref opus_genericctls, |
| | | * @ref opus_decoderctls, or @ref opus_multistream_ctls. |
| | | * @see opus_genericctls |
| | | * @see opus_decoderctls |
| | | * @see opus_multistream_ctls |
| | | */ |
| | | OPUS_EXPORT int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...) OPUS_ARG_NONNULL(1); |
| | | |
| | | /** Frees an <code>OpusMSDecoder</code> allocated by |
| | | * opus_multistream_decoder_create(). |
| | | * @param st <tt>OpusMSDecoder</tt>: Multistream decoder state to be freed. |
| | | */ |
| | | OPUS_EXPORT void opus_multistream_decoder_destroy(OpusMSDecoder *st); |
| | | |
| | | /**@}*/ |
| | | |
| | | /**@}*/ |
| | | |
| | | #ifdef __cplusplus |
| | | } |
| | | #endif |
| | | |
| | | #endif /* OPUS_MULTISTREAM_H */ |
New file |
| | |
| | | /* (C) COPYRIGHT 1994-2002 Xiph.Org Foundation */ |
| | | /* Modified by Jean-Marc Valin */ |
| | | /* |
| | | 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. |
| | | |
| | | 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. |
| | | */ |
| | | /* opus_types.h based on ogg_types.h from libogg */ |
| | | |
| | | /** |
| | | @file opus_types.h |
| | | @brief Opus reference implementation types |
| | | */ |
| | | #ifndef OPUS_TYPES_H |
| | | #define OPUS_TYPES_H |
| | | |
| | | /* Use the real stdint.h if it's there (taken from Paul Hsieh's pstdint.h) */ |
| | | #if (defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)) || defined (HAVE_STDINT_H)) |
| | | #include <stdint.h> |
| | | |
| | | typedef int16_t opus_int16; |
| | | typedef uint16_t opus_uint16; |
| | | typedef int32_t opus_int32; |
| | | typedef uint32_t opus_uint32; |
| | | #elif defined(_WIN32) |
| | | |
| | | # if defined(__CYGWIN__) |
| | | # include <_G_config.h> |
| | | typedef _G_int32_t opus_int32; |
| | | typedef _G_uint32_t opus_uint32; |
| | | typedef _G_int16 opus_int16; |
| | | typedef _G_uint16 opus_uint16; |
| | | # elif defined(__MINGW32__) |
| | | typedef short opus_int16; |
| | | typedef unsigned short opus_uint16; |
| | | typedef int opus_int32; |
| | | typedef unsigned int opus_uint32; |
| | | # elif defined(__MWERKS__) |
| | | typedef int opus_int32; |
| | | typedef unsigned int opus_uint32; |
| | | typedef short opus_int16; |
| | | typedef unsigned short opus_uint16; |
| | | # else |
| | | /* MSVC/Borland */ |
| | | typedef __int32 opus_int32; |
| | | typedef unsigned __int32 opus_uint32; |
| | | typedef __int16 opus_int16; |
| | | typedef unsigned __int16 opus_uint16; |
| | | # endif |
| | | |
| | | #elif defined(__MACOS__) |
| | | |
| | | # include <sys/types.h> |
| | | typedef SInt16 opus_int16; |
| | | typedef UInt16 opus_uint16; |
| | | typedef SInt32 opus_int32; |
| | | typedef UInt32 opus_uint32; |
| | | |
| | | #elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */ |
| | | |
| | | # include <sys/types.h> |
| | | typedef int16_t opus_int16; |
| | | typedef u_int16_t opus_uint16; |
| | | typedef int32_t opus_int32; |
| | | typedef u_int32_t opus_uint32; |
| | | |
| | | #elif defined(__BEOS__) |
| | | |
| | | /* Be */ |
| | | # include <inttypes.h> |
| | | typedef int16 opus_int16; |
| | | typedef u_int16 opus_uint16; |
| | | typedef int32_t opus_int32; |
| | | typedef u_int32_t opus_uint32; |
| | | |
| | | #elif defined (__EMX__) |
| | | |
| | | /* OS/2 GCC */ |
| | | typedef short opus_int16; |
| | | typedef unsigned short opus_uint16; |
| | | typedef int opus_int32; |
| | | typedef unsigned int opus_uint32; |
| | | |
| | | #elif defined (DJGPP) |
| | | |
| | | /* DJGPP */ |
| | | typedef short opus_int16; |
| | | typedef unsigned short opus_uint16; |
| | | typedef int opus_int32; |
| | | typedef unsigned int opus_uint32; |
| | | |
| | | #elif defined(R5900) |
| | | |
| | | /* PS2 EE */ |
| | | typedef int opus_int32; |
| | | typedef unsigned opus_uint32; |
| | | typedef short opus_int16; |
| | | typedef unsigned short opus_uint16; |
| | | |
| | | #elif defined(__SYMBIAN32__) |
| | | |
| | | /* Symbian GCC */ |
| | | typedef signed short opus_int16; |
| | | typedef unsigned short opus_uint16; |
| | | typedef signed int opus_int32; |
| | | typedef unsigned int opus_uint32; |
| | | |
| | | #elif defined(CONFIG_TI_C54X) || defined (CONFIG_TI_C55X) |
| | | |
| | | typedef short opus_int16; |
| | | typedef unsigned short opus_uint16; |
| | | typedef long opus_int32; |
| | | typedef unsigned long opus_uint32; |
| | | |
| | | #elif defined(CONFIG_TI_C6X) |
| | | |
| | | typedef short opus_int16; |
| | | typedef unsigned short opus_uint16; |
| | | typedef int opus_int32; |
| | | typedef unsigned int opus_uint32; |
| | | |
| | | #else |
| | | |
| | | /* Give up, take a reasonable guess */ |
| | | typedef short opus_int16; |
| | | typedef unsigned short opus_uint16; |
| | | typedef int opus_int32; |
| | | typedef unsigned int opus_uint32; |
| | | |
| | | #endif |
| | | |
| | | #define opus_int int /* used for counters etc; at least 16 bits */ |
| | | #define opus_int64 long long |
| | | #define opus_int8 signed char |
| | | |
| | | #define opus_uint unsigned int /* used for counters etc; at least 16 bits */ |
| | | #define opus_uint64 unsigned long long |
| | | #define opus_uint8 unsigned char |
| | | |
| | | #endif /* OPUS_TYPES_H */ |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
| | | <plist version="1.0"> |
| | | <dict> |
| | | <key>JPush_AppKey</key> |
| | | <string>111a5f817592ddc68edc802c</string> |
| | | <key>TTTrack_AppID</key> |
| | | <string>155761</string> |
| | | <key>TrackingIO_AppKey</key> |
| | | <string>12aef4c284c6996703765fe9f7422428</string> |
| | | </dict> |
| | | </plist> |
New file |
| | |
| | | // |
| | | // UniversalSDK.h |
| | | // Unity-iPhone |
| | | // |
| | | // Created by 蔡瀚 on 2018/4/24. |
| | | // |
| | | |
| | | #ifndef __UNIVERSALSDK_H_ |
| | | #define __UNIVERSALSDK_H_ |
| | | |
| | | #import <Foundation/Foundation.h> |
| | | #import <UIKit/UIKit.h> |
| | | |
| | | #define UNITY_OBJ_NAME "SDKUtility" |
| | | #define UNITY_FUNC_NAME "HandleSdkMessage" |
| | | |
| | | #define PRODUCT_CODE @"96065423134516611008224414549989" |
| | | #define PRODUCT_KEY @"69623854" |
| | | |
| | | #define S2U_BatteryLevel 1 |
| | | #define S2U_BatteryCharging 2 |
| | | #define S2U_DeviceInfo 3 |
| | | #define S2U_PushClientID 4 |
| | | #define S2U_FreePlatformInitOk 10 |
| | | #define S2U_FreePlatformInitFail 11 |
| | | #define S2U_FreePlatformLoginOk 12 |
| | | #define S2U_FreePlatformLoginFail 13 |
| | | #define S2U_FreePlatformLoginCancel 14 |
| | | #define S2U_FreePlatformLogoutOk 15 |
| | | #define S2U_FreePlatformLogoutFail 16 |
| | | #define S2U_FreePlatformSwitchAccountOk 17 |
| | | #define S2U_FreePlatformPayOk 18 |
| | | #define S2U_FreePlatformPayFail 19 |
| | | #define S2U_FreePlatformPayCancel 20 |
| | | #define S2U_FreePlatformRegisterOk 21 |
| | | #define S2U_SdkInitComplete 90 |
| | | |
| | | #define U2S_BatteryListenStart 1 |
| | | #define U2S_BatteryListenStop 2 |
| | | #define U2S_CopyContent 7 |
| | | #define U2S_OpenWebView 8 |
| | | #define U2S_Init 9 |
| | | #define U2S_FreePlatformInit 100 |
| | | #define U2S_FreePlatformLogin 101 |
| | | #define U2S_FreePlatformLogout 102 |
| | | #define U2S_FreePlatformSwitchAccount 103 |
| | | #define U2S_FreePlatformPay 104 |
| | | #define U2S_PayFinished 105 |
| | | #define U2S_CreateRole 106 |
| | | #define U2S_RoleLogin 107 |
| | | #define U2S_RoleLevelUp 108 |
| | | #define U2S_JPushAddLocalMessage 200 |
| | | #define U2S_JPushRemoveLocalMessage 201 |
| | | #define U2S_MakeKeyAndVisible 300 |
| | | #define U2S_SendRegistEvent 500 |
| | | #define U2S_SendLoginEvent 600 |
| | | |
| | | #define KIsiPhoneX ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1125, 2436), [[UIScreen mainScreen] currentMode].size) : NO) |
| | | |
| | | static BOOL JPush_IsProduction = FALSE; |
| | | |
| | | @interface UniversalSDK : NSObject { |
| | | UIWebView* m_UIWebView; |
| | | UIButton* m_CloseBtn; |
| | | } |
| | | |
| | | -(void) HandleUnityMessage:(NSString*) json; |
| | | -(void) Init; |
| | | -(id) APNativeJSONObject:(NSData*) data; |
| | | -(NSData*) APNativeJSONData:(id) obj; |
| | | -(void) RemoveLocalNotificationWithIdentifierKey:(NSString*) idKey; |
| | | |
| | | -(void) QuickSDKInit:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions; |
| | | |
| | | @end |
| | | |
| | | #endif |
New file |
| | |
| | | // |
| | | // UniversalSDK.m |
| | | // Unity-iPhone |
| | | // |
| | | // Created by 蔡瀚 on 2018/4/24. |
| | | // |
| | | |
| | | #import "UniversalSDK.h" |
| | | #import "AdSupport/AdSupport.h" |
| | | #import "opus.h" |
| | | #ifdef NSFoundationVersionNumber_iOS_9_x_Max |
| | | #import <UserNotifications/UserNotifications.h> |
| | | #endif |
| | | #import "SystemConfiguration/CaptiveNetwork.h" |
| | | #import <SMPCQuickSDK/SMPCQuickSDK.h> |
| | | |
| | | @interface UniversalSDK()<UIWebViewDelegate> |
| | | @end |
| | | |
| | | @implementation UniversalSDK |
| | | |
| | | #define CHANNEL_NUM 1 |
| | | |
| | | static int s_frequency = 16000; |
| | | static int s_bitRate = 20000; |
| | | static int s_bandMode = OPUS_BANDWIDTH_WIDEBAND; |
| | | static int s_frameSize = 160; |
| | | static int sBatteryLevel = -1; |
| | | static int sBatteryState = -1; |
| | | static NSString* sAppID; |
| | | static NSString* sGameID; |
| | | static NSString* sUserName; |
| | | static NSThread* _thread; |
| | | |
| | | -(void) Init |
| | | { |
| | | UIDevice *_device = [UIDevice currentDevice]; |
| | | _device.batteryMonitoringEnabled = true; |
| | | |
| | | NSString* _uniqueID = [[NSUserDefaults standardUserDefaults] objectForKey:@"tsw_unique_id"]; |
| | | //获取IDFA |
| | | NSString* _idfa = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString]; |
| | | |
| | | if(_uniqueID == NULL || [_uniqueID length] <= 0) |
| | | { |
| | | //判断IDFA是否为空 |
| | | BOOL isEmpty = [[_idfa stringByReplacingOccurrencesOfString:@"-" withString:@""] stringByReplacingOccurrencesOfString:@"0" withString:@""].length; |
| | | if (isEmpty) { |
| | | //不为空,将IDFA作为唯一标识 |
| | | _uniqueID = _idfa; |
| | | } |
| | | else { |
| | | //为空,获取UUID作为唯一标识 |
| | | _uniqueID = [[[UIDevice currentDevice] identifierForVendor] UUIDString]; |
| | | } |
| | | |
| | | //保存唯一设备标识,如已存在则不进行任何处理 |
| | | [[NSUserDefaults standardUserDefaults] setObject:_uniqueID forKey:@"tsw_unique_id"]; |
| | | [[NSUserDefaults standardUserDefaults] synchronize]; |
| | | } |
| | | |
| | | // 取得UserAgent |
| | | UIWebView* _webView = [[UIWebView alloc] initWithFrame:CGRectZero]; |
| | | NSString* _userAgent = [_webView stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"]; |
| | | |
| | | // 发送设备信息 |
| | | NSMutableDictionary *_dict = [NSMutableDictionary dictionaryWithObjectsAndKeys: |
| | | _uniqueID,@"unique_id", |
| | | _idfa,@"android_id", |
| | | [NSNumber numberWithInt:S2U_DeviceInfo],@"code", |
| | | _userAgent,@"userAgent",nil]; |
| | | [self SendMessageToUnity:_dict]; |
| | | } |
| | | |
| | | -(void)SendMessageToUnity:(NSDictionary*)dict |
| | | { |
| | | BOOL _result = [NSJSONSerialization isValidJSONObject:dict]; |
| | | if(_result) |
| | | { |
| | | NSData* _jsonData = [NSJSONSerialization dataWithJSONObject:dict options:0 error:NULL]; |
| | | UnitySendMessage(UNITY_OBJ_NAME, UNITY_FUNC_NAME, |
| | | [[[NSString alloc] initWithData:_jsonData encoding:NSUTF8StringEncoding] UTF8String]); |
| | | } |
| | | } |
| | | |
| | | -(void) BatteryThread { |
| | | while (TRUE) |
| | | { |
| | | [NSThread sleepForTimeInterval:1]; |
| | | |
| | | UIDevice *_device = [UIDevice currentDevice]; |
| | | |
| | | int _state = [_device batteryState]; |
| | | if(_state != sBatteryState){ |
| | | sBatteryState = _state; |
| | | NSDictionary *_dict = [NSDictionary dictionaryWithObjectsAndKeys: |
| | | [NSNumber numberWithInt:sBatteryState], @"status", |
| | | [NSNumber numberWithInt:S2U_BatteryCharging], @"code", nil]; |
| | | |
| | | [self SendMessageToUnity:_dict]; |
| | | } |
| | | |
| | | int _level = (int)([_device batteryLevel] * 100); |
| | | if(_level != sBatteryLevel){ |
| | | sBatteryLevel = _level; |
| | | NSDictionary *_dict = [NSDictionary dictionaryWithObjectsAndKeys: |
| | | [NSNumber numberWithInt:sBatteryLevel], @"level", |
| | | [NSNumber numberWithInt:S2U_BatteryLevel], @"code", nil]; |
| | | |
| | | [self SendMessageToUnity:_dict]; |
| | | } |
| | | } |
| | | } |
| | | |
| | | -(void) OpenURL:(NSString*) url { |
| | | |
| | | if(m_UIWebView != NULL) { |
| | | [self btnClick:NULL]; |
| | | return; |
| | | } |
| | | |
| | | CGRect _bounds = UnityGetMainWindow().bounds; |
| | | |
| | | float _scale = _bounds.size.width / 1334; |
| | | |
| | | float _width = 982 * _scale; |
| | | float _height = 560 * _scale; |
| | | |
| | | float _offsetX = (_bounds.size.width - _width) * .5f; |
| | | float _offsetY = (_bounds.size.height - _height) * .5f; |
| | | |
| | | m_UIWebView = [[UIWebView alloc] initWithFrame:CGRectMake(_offsetX, _offsetY, _width, _height)]; |
| | | m_UIWebView.delegate = self; |
| | | m_UIWebView.scalesPageToFit = YES ; |
| | | m_UIWebView.scrollView.scrollEnabled = YES; |
| | | m_UIWebView.scrollView.bounces = NO; |
| | | NSURLRequest *request =[NSURLRequest requestWithURL:[NSURL URLWithString:url]]; |
| | | [m_UIWebView loadRequest:request]; |
| | | } |
| | | |
| | | -(void) btnClick:(UIButton*)sender { |
| | | [m_CloseBtn removeFromSuperview]; |
| | | [m_CloseBtn removeTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside]; |
| | | m_CloseBtn = NULL; |
| | | |
| | | NSURLCache *_cache = [NSURLCache sharedURLCache]; |
| | | [_cache removeAllCachedResponses]; |
| | | [_cache setDiskCapacity:0]; |
| | | [_cache setMemoryCapacity:0]; |
| | | |
| | | [m_UIWebView removeFromSuperview]; |
| | | m_UIWebView = NULL; |
| | | } |
| | | |
| | | -(void)webViewDidStartLoad:(UIWebView *)webView{ |
| | | } |
| | | |
| | | -(void)webViewDidFinishLoad:(UIWebView *)webView{ |
| | | |
| | | [UnityGetMainWindow().rootViewController.view addSubview:m_UIWebView]; |
| | | CGRect _bounds = UnityGetMainWindow().bounds; |
| | | |
| | | float _scale = _bounds.size.width / 1334; |
| | | |
| | | float _width = 982 * _scale; |
| | | float _height = 560 * _scale; |
| | | |
| | | m_CloseBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect]; |
| | | [m_CloseBtn setFrame:CGRectMake(_width - 455 * _scale, _height - 86 * _scale, 180 * _scale, 72 * _scale)]; |
| | | [m_CloseBtn setTitle:@"我知道了" forState:UIControlStateNormal]; |
| | | |
| | | NSString *_bundlePath = [[NSBundle mainBundle] pathForResource:@"The2thWorldRES.bundle" ofType:nil]; |
| | | NSBundle *_bundle = [NSBundle bundleWithPath:_bundlePath]; |
| | | NSString *pic1Path = [_bundle pathForResource:@"TY_AN_34.png" ofType:nil]; |
| | | |
| | | [m_CloseBtn setBackgroundImage:[UIImage imageWithContentsOfFile:pic1Path] forState:UIControlStateNormal]; |
| | | [m_CloseBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; |
| | | [m_CloseBtn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside]; |
| | | |
| | | [m_UIWebView addSubview:m_CloseBtn]; |
| | | } |
| | | |
| | | -(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{ |
| | | } |
| | | |
| | | -(void)QuickSDKInit:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { |
| | | |
| | | // 监听初始化 |
| | | [[NSNotificationCenter defaultCenter] addObserver:self |
| | | selector:@selector(smpcQpInitResult:) |
| | | name:kSmpcQuickSDKNotiInitDidFinished |
| | | object:nil]; |
| | | // 监听登录 |
| | | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(smpcQpLoginResult:) name:kSmpcQuickSDKNotiLogin object:nil]; |
| | | // 监听注销 |
| | | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(smpcQpLogoutResult:) name:kSmpcQuickSDKNotiLogout object:nil]; |
| | | // 监听充值结果 |
| | | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(smpcQpRechargeResult:) name:kSmpcQuickSDKNotiRecharge object:nil]; |
| | | |
| | | // --------------------- 初始化 -------------------------- |
| | | SMPCQuickSDKInitConfigure *cfg = [[SMPCQuickSDKInitConfigure alloc] init]; |
| | | cfg.productKey = PRODUCT_KEY; |
| | | cfg.productCode = PRODUCT_CODE; |
| | | [[SMPCQuickSDK defaultInstance] initWithConfig:cfg application:application didFinishLaunchingWithOptions:launchOptions]; |
| | | // ------------------------------------------------------ |
| | | } |
| | | |
| | | - (void)smpcQpInitResult:(NSNotification *)notify { |
| | | NSLog(@"init result:%@",notify); |
| | | NSDictionary *userInfo = notify.userInfo; |
| | | int errorCode = [userInfo[kSmpcQuickSDKKeyError] intValue]; |
| | | switch (errorCode) { |
| | | case SMPC_QUICK_SDK_ERROR_NONE: |
| | | { |
| | | NSLog(@"初始化成功"); |
| | | // NSString *_appid = [[SMPCQuickSDK defaultInstance] getConfigValue:@"zfappid"]; |
| | | // if (_appid == nil || [_appid isEqualToString:@""]) |
| | | // { |
| | | // _appid = sAppID; |
| | | // } |
| | | NSString *_appid = sAppID; |
| | | NSLog(@"init _appid:%@",_appid); |
| | | |
| | | NSMutableDictionary *_dict = [NSMutableDictionary dictionaryWithObjectsAndKeys: |
| | | [NSNumber numberWithInt:S2U_SdkInitComplete], @"code", |
| | | @"quick", @"channelPlatform", |
| | | _appid, @"yj_appid", _appid, @"yj_spid", nil]; |
| | | [self SendMessageToUnity:_dict]; |
| | | } |
| | | break; |
| | | case SMPC_QUICK_SDK_ERROR_INIT_FAILED: |
| | | default: |
| | | { |
| | | //初始化失败 |
| | | NSLog(@"渠道初始化失败"); |
| | | } |
| | | break; |
| | | } |
| | | |
| | | } |
| | | |
| | | - (void)smpcQpLoginResult:(NSNotification *)notify { |
| | | NSLog(@"登录成功通知%@",notify); |
| | | int error = [[[notify userInfo] objectForKey:kSmpcQuickSDKKeyError] intValue]; |
| | | NSDictionary *userInfo = [notify userInfo]; |
| | | if (error == 0) { |
| | | NSString *uid = [[SMPCQuickSDK defaultInstance] userId]; |
| | | NSString *gameUID = [NSString stringWithFormat:@"%@@%d", uid, [SMPCQuickSDK defaultInstance].channelType]; |
| | | NSString *UserName = [[SMPCQuickSDK defaultInstance] userId]; |
| | | //获取user_token,用于从服务器去验证用户信息 |
| | | NSString *user_token = userInfo[kSmpcQuickSDKKeyUserToken]; |
| | | |
| | | NSDictionary *_dict = [NSDictionary dictionaryWithObjectsAndKeys: |
| | | [NSDictionary dictionaryWithObjectsAndKeys:user_token, @"token", |
| | | UserName, @"userName", |
| | | gameUID, @"account", nil],@"info", |
| | | [NSNumber numberWithInt:S2U_FreePlatformLoginOk], @"code", nil]; |
| | | [self SendMessageToUnity:_dict]; |
| | | } |
| | | } |
| | | |
| | | - (void)smpcQpLogoutResult:(NSNotification *)notify { |
| | | NSLog(@"%s",__func__); |
| | | NSDictionary *userInfo = notify.userInfo; |
| | | int errorCode = [userInfo[kSmpcQuickSDKKeyError] intValue]; |
| | | switch (errorCode) { |
| | | case SMPC_QUICK_SDK_ERROR_NONE: |
| | | { |
| | | NSLog(@"注销成功"); |
| | | //注销成功 |
| | | NSDictionary *_dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:S2U_FreePlatformLogoutOk], @"code", nil]; |
| | | [self SendMessageToUnity:_dict]; |
| | | } |
| | | break; |
| | | case SMPC_QUICK_SDK_ERROR_LOGOUT_FAIL: |
| | | default: |
| | | { |
| | | //注销失败 |
| | | NSLog(@"注销失败"); |
| | | } |
| | | break; |
| | | } |
| | | if (errorCode == SMPC_QUICK_SDK_ERROR_NONE) { |
| | | |
| | | } |
| | | |
| | | } |
| | | |
| | | - (void)smpcQpRechargeResult:(NSNotification *)notify{ |
| | | NSLog(@"充值结果%@",notify); |
| | | NSDictionary *userInfo = notify.userInfo; |
| | | int error = [[userInfo objectForKey:kSmpcQuickSDKKeyError] intValue]; |
| | | switch (error) { |
| | | case SMPC_QUICK_SDK_ERROR_NONE: |
| | | { |
| | | //充值成功 |
| | | //QuickSDK订单号,cp下单时传入的订单号,渠道sdk的订单号,cp下单时传入的扩展参数 |
| | | NSString *orderID = userInfo[kSmpcQuickSDKKeyOrderId]; |
| | | NSString *cpOrderID = userInfo[kSmpcQuickSDKKeyCpOrderId]; |
| | | NSLog(@"充值成功数据:%@,%@",orderID,cpOrderID); |
| | | NSDictionary *_dict = [NSDictionary dictionaryWithObjectsAndKeys: |
| | | [NSNumber numberWithInt:S2U_FreePlatformPayOk], @"code", nil]; |
| | | [self SendMessageToUnity:_dict]; |
| | | } |
| | | break; |
| | | case SMPC_QUICK_SDK_ERROR_RECHARGE_CANCELLED: |
| | | case SMPC_QUICK_SDK_ERROR_RECHARGE_FAILED: |
| | | { |
| | | //充值失败 |
| | | NSString *orderID = userInfo[kSmpcQuickSDKKeyOrderId]; |
| | | NSString *cpOrderID = userInfo[kSmpcQuickSDKKeyCpOrderId]; |
| | | NSLog(@"充值失败数据%@,%@",orderID,cpOrderID); |
| | | NSDictionary *_dict = [NSDictionary dictionaryWithObjectsAndKeys: |
| | | [NSNumber numberWithInt:S2U_FreePlatformPayFail], @"code", nil]; |
| | | [self SendMessageToUnity:_dict]; |
| | | } |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | |
| | | -(id) APNativeJSONObject:(NSData *)data{ |
| | | if (!data) { |
| | | return nil; |
| | | } |
| | | |
| | | NSError *error = nil; |
| | | id retId = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; |
| | | |
| | | if (error) { |
| | | NSLog(@"%s trans data to obj with error: %@", __func__, error); |
| | | return nil; |
| | | } |
| | | |
| | | return retId; |
| | | } |
| | | |
| | | -(void)HandleUnityMessage:(NSString *)json { |
| | | |
| | | NSLog(@"收到Unity发来的消息 => %@", json); |
| | | |
| | | NSData *_jsonData = [json dataUsingEncoding:NSUTF8StringEncoding]; |
| | | NSDictionary *_dict = [self APNativeJSONObject:_jsonData]; |
| | | |
| | | switch([[_dict objectForKey:@"code"] intValue]){ |
| | | case U2S_Init: |
| | | sAppID = _dict[@"appID"]; |
| | | sGameID = _dict[@"gameID"]; |
| | | [self Init]; |
| | | |
| | | break; |
| | | case U2S_CopyContent: |
| | | [UIPasteboard generalPasteboard].string = _dict[@"content"]; |
| | | break; |
| | | case U2S_FreePlatformInit: |
| | | break; |
| | | case U2S_MakeKeyAndVisible: |
| | | { |
| | | UIWindow * _window = [[UIApplication sharedApplication].delegate window]; |
| | | if (_window != nil && _window.rootViewController != nil) { |
| | | [_window makeKeyAndVisible]; |
| | | } |
| | | } |
| | | break; |
| | | case U2S_OpenWebView: |
| | | [self OpenURL:_dict[@"url"]]; |
| | | break; |
| | | case U2S_FreePlatformLogin: |
| | | { |
| | | int error = [[SMPCQuickSDK defaultInstance] login]; |
| | | if (error != 0) { |
| | | NSLog(@"U2S_FreePlatformLogin => %d",error); |
| | | } |
| | | } |
| | | break; |
| | | case U2S_FreePlatformLogout: |
| | | { |
| | | [[SMPCQuickSDK defaultInstance] logout]; |
| | | } |
| | | break; |
| | | case U2S_CreateRole: |
| | | { |
| | | // 更新角色信息 |
| | | SMPCQuickSDKGameRoleInfo *gameRoleInfo = [SMPCQuickSDKGameRoleInfo new]; |
| | | gameRoleInfo.serverName = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"serverName"]]; |
| | | gameRoleInfo.gameRoleName = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"roleName"]]; |
| | | gameRoleInfo.serverId = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"sid"]]; //需要是数字字符串 |
| | | gameRoleInfo.gameRoleID = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"roleID"]]; |
| | | gameRoleInfo.gameUserBalance = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"money"]]; |
| | | gameRoleInfo.vipLevel = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"vipLevel"]]; |
| | | gameRoleInfo.gameUserLevel = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"level"]]; |
| | | gameRoleInfo.partyName = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"familyName"]]; |
| | | gameRoleInfo.creatTime = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"createTime"]]; |
| | | |
| | | [[SMPCQuickSDK defaultInstance] updateRoleInfoWith:gameRoleInfo isCreate:YES];//如果这个角色是刚刚创建的,这里isCreate可以传YES |
| | | break; |
| | | } |
| | | case U2S_RoleLogin: |
| | | { |
| | | // 更新角色信息 |
| | | SMPCQuickSDKGameRoleInfo *gameRoleInfo = [SMPCQuickSDKGameRoleInfo new]; |
| | | gameRoleInfo.serverName = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"serverName"]]; |
| | | gameRoleInfo.gameRoleName = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"roleName"]]; |
| | | gameRoleInfo.serverId = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"sid"]]; //需要是数字字符串 |
| | | gameRoleInfo.gameRoleID = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"roleID"]]; |
| | | gameRoleInfo.gameUserBalance = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"money"]]; |
| | | gameRoleInfo.vipLevel = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"vipLevel"]]; |
| | | gameRoleInfo.gameUserLevel = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"level"]]; |
| | | gameRoleInfo.partyName = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"familyName"]]; |
| | | gameRoleInfo.creatTime = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"createTime"]]; |
| | | |
| | | [[SMPCQuickSDK defaultInstance] updateRoleInfoWith:gameRoleInfo isCreate:NO];//如果这个角色是刚刚创建的,这里isCreate可以传YES |
| | | break; |
| | | } |
| | | |
| | | case U2S_RoleLevelUp: |
| | | { |
| | | // 更新角色信息 |
| | | SMPCQuickSDKGameRoleInfo *gameRoleInfo = [SMPCQuickSDKGameRoleInfo new]; |
| | | gameRoleInfo.serverName = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"serverName"]]; |
| | | gameRoleInfo.gameRoleName = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"roleName"]]; |
| | | gameRoleInfo.serverId = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"sid"]]; //需要是数字字符串 |
| | | gameRoleInfo.gameRoleID = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"roleID"]]; |
| | | gameRoleInfo.gameUserBalance = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"money"]]; |
| | | gameRoleInfo.vipLevel = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"vipLevel"]]; |
| | | gameRoleInfo.gameUserLevel = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"level"]]; |
| | | gameRoleInfo.partyName = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"familyName"]]; |
| | | gameRoleInfo.creatTime = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"createTime"]]; |
| | | |
| | | [[SMPCQuickSDK defaultInstance] updateRoleInfoWith:gameRoleInfo isCreate:NO];//如果这个角色是刚刚创建的,这里isCreate可以传YES |
| | | break; |
| | | } |
| | | case U2S_FreePlatformPay: |
| | | { |
| | | SMPCQuickSDKGameRoleInfo *role = [[SMPCQuickSDKGameRoleInfo alloc] init]; |
| | | SMPCQuickSDKPayOrderInfo *order = [[SMPCQuickSDKPayOrderInfo alloc] init]; |
| | | |
| | | role.serverName = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"serverName"]]; |
| | | role.gameRoleName = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"roleName"]]; |
| | | role.serverId = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"sid"]]; //需要是数字字符串 |
| | | role.gameRoleID = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"roleID"]]; |
| | | role.gameUserBalance = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"money"]]; |
| | | role.vipLevel = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"vipLevel"]]; |
| | | role.gameUserLevel = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"level"]]; |
| | | role.partyName = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"familyName"]]; |
| | | role.creatTime = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"createTime"]]; |
| | | |
| | | order.goodsID = [NSString stringWithFormat:@"%@", [_dict objectForKey:@"cpInfo"]]; //必填 iap时注意和苹果开发者后台一致,或者渠道映射的 |
| | | order.productName = [NSString stringWithFormat:@"%@", [_dict objectForKey:@"title"]];//必填 |
| | | order.cpOrderID = [NSString stringWithFormat:@"%@", [_dict objectForKey:@"orderId"]]; //必填 游戏订单号 |
| | | order.count = 1; //必填 数量 |
| | | order.amount = [[_dict objectForKey:@"mount"] floatValue]; //必填 总价 |
| | | |
| | | // NSString *_appid = [[SMPCQuickSDK defaultInstance] getConfigValue:@"zfappid"]; |
| | | // if (_appid == nil || [_appid isEqualToString:@""]) |
| | | // { |
| | | // _appid = sAppID; |
| | | // } |
| | | NSString *_appid = sAppID; |
| | | order.extrasParams = [NSString stringWithFormat:@"{\"appid\":\"%@\",\"cpinfo\":\"%@\",\"cporderid\":\"%@\"}", |
| | | _appid, |
| | | [_dict objectForKey:@"cpInfo"], |
| | | [_dict objectForKey:@"orderId"] |
| | | ]; |
| | | // //个别渠道要求单价*数量==总价 |
| | | // if([SMPCQuickSDK defaultInstance].channelType == 9999){ |
| | | // //通过判断渠道号处理特定渠道的参数 |
| | | // order.goodsID = @"productlist.name"; |
| | | // } |
| | | int error = [[SMPCQuickSDK defaultInstance] payOrderInfo:order |
| | | roleInfo:role]; |
| | | if (error!=0) |
| | | NSLog(@"%d", error); |
| | | } |
| | | break; |
| | | case U2S_BatteryListenStart: |
| | | if(_thread == NULL) |
| | | { |
| | | _thread = [[NSThread alloc] initWithTarget:self selector:@selector(BatteryThread) object:nil]; |
| | | [_thread setName:@"BatteryCheck"]; |
| | | } |
| | | if(![_thread isExecuting]) |
| | | { |
| | | [_thread start]; |
| | | } |
| | | break; |
| | | case U2S_BatteryListenStop: |
| | | break; |
| | | } |
| | | } |
| | | @end |
| | | |
| | | extern "C" void native_opus_init(int frequency, int bitRate, int bandMode) |
| | | { |
| | | s_frequency = frequency; |
| | | s_bandMode = bandMode; |
| | | s_bitRate = bitRate; |
| | | s_frameSize = frequency / 100; |
| | | } |
| | | |
| | | extern "C" int native_opus_encode(opus_int16 *pcm, int len, unsigned char *opus) |
| | | { |
| | | int errorCode = 0; |
| | | opus_int32 skip = 0; |
| | | OpusEncoder *enc = opus_encoder_create(s_frequency, CHANNEL_NUM, OPUS_APPLICATION_VOIP, &errorCode); |
| | | if (OPUS_OK != errorCode) { |
| | | enc = NULL; |
| | | return -1; |
| | | } |
| | | |
| | | opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(s_bandMode)); |
| | | opus_encoder_ctl(enc, OPUS_SET_BITRATE(s_bitRate)); |
| | | opus_encoder_ctl(enc, OPUS_SET_VBR(1)); |
| | | opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(10)); |
| | | opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(0)); |
| | | opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(OPUS_SIGNAL_VOICE)); |
| | | opus_encoder_ctl(enc, OPUS_SET_DTX(0)); |
| | | opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(0)); |
| | | opus_encoder_ctl(enc, OPUS_GET_LOOKAHEAD(&skip)); |
| | | opus_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(16)); |
| | | |
| | | unsigned char *rbytes = opus; |
| | | opus_int16 *frame = pcm; |
| | | int totalSize = 0; |
| | | while (len >= s_frameSize) |
| | | { |
| | | opus_int32 length = opus_encode(enc, frame, s_frameSize, rbytes + sizeof(char), s_bitRate); |
| | | rbytes[0] = length; |
| | | frame += s_frameSize; |
| | | rbytes += length + sizeof(char); |
| | | len -= s_frameSize; |
| | | totalSize += length; |
| | | } |
| | | opus_encoder_destroy(enc); |
| | | return totalSize; |
| | | } |
| | | |
| | | extern "C" int native_opus_decode(unsigned char *opus, int len, short *pcm) |
| | | { |
| | | int err = 0; |
| | | //opus_int32 skip = 0; |
| | | |
| | | OpusDecoder *dec = opus_decoder_create(s_frequency, CHANNEL_NUM, &err); |
| | | if (err != OPUS_OK) { |
| | | dec = NULL; |
| | | return -1; |
| | | } |
| | | |
| | | while (len > 0) |
| | | { |
| | | int frame_opus_length = opus[0]; |
| | | int length = opus_decode(dec, opus + sizeof(char), frame_opus_length, pcm, s_frameSize, 0); |
| | | opus += sizeof(char) + frame_opus_length; |
| | | pcm += s_frameSize; |
| | | len = len - frame_opus_length - sizeof(char); |
| | | } |
| | | opus_decoder_destroy(dec); |
| | | return 0; |
| | | } |