New file |
| | |
| | | // |
| | | // UniversalSDK.m |
| | | // Unity-iPhone |
| | | // |
| | | // |
| | | |
| | | #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 <SohaSDK/SohaSetting.h> |
| | | #import <SohaSDK/SohaSDK.h> |
| | | #import <SohaSDK/Soha.h> |
| | | |
| | | |
| | | @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; |
| | | |
| | | static int initedState=0; //初始化状态,0初始化中,1成功,2失败 |
| | | |
| | | static NSString * const kClientID = @"468442318367-ocoqrm0kei0gpkrnnq1ql628v4g4dbqd.apps.googleusercontent.com"; |
| | | |
| | | -(id)init |
| | | { |
| | | self = [super init]; |
| | | |
| | | m_fakeUIWebView = [[WKWebView alloc] initWithFrame:CGRectZero]; |
| | | NSURL *url = [NSURL URLWithString:@"www.baidu.com"]; |
| | | NSURLRequest *request = [NSURLRequest requestWithURL:url |
| | | cachePolicy:NSURLRequestUseProtocolCachePolicy |
| | | timeoutInterval:10.f]; |
| | | [m_fakeUIWebView loadRequest:request]; |
| | | |
| | | return self; |
| | | } |
| | | -(void) Init |
| | | { |
| | | UIDevice *_device = [UIDevice currentDevice]; |
| | | _device.batteryMonitoringEnabled = true; |
| | | |
| | | NSString* _uniqueID = [[NSUserDefaults standardUserDefaults] objectForKey:@"tsw_unique_id"]; |
| | | |
| | | if(_uniqueID == NULL || [_uniqueID length] <= 0) |
| | | { |
| | | _uniqueID = [[[UIDevice currentDevice] identifierForVendor] UUIDString]; |
| | | |
| | | //保存唯一设备标识,如已存在则不进行任何处理 |
| | | [[NSUserDefaults standardUserDefaults] setObject:_uniqueID forKey:@"tsw_unique_id"]; |
| | | [[NSUserDefaults standardUserDefaults] synchronize]; |
| | | } |
| | | |
| | | // 取得UserAgent |
| | | [m_fakeUIWebView evaluateJavaScript:@"navigator.userAgent" completionHandler:^(id _Nullable userAgent, NSError * _Nullable error) { |
| | | |
| | | NSLog(@"%@", userAgent); |
| | | NSString* _userAgent = [NSString stringWithFormat:@"%@", userAgent]; |
| | | // 发送设备信息 |
| | | NSMutableDictionary *_dict = [NSMutableDictionary dictionaryWithObjectsAndKeys: |
| | | _uniqueID,@"unique_id", |
| | | _uniqueID,@"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 = [[WKWebView alloc] initWithFrame:CGRectMake(_offsetX, _offsetY, _width, _height)]; |
| | | m_UIWebView.UIDelegate = self; |
| | | m_UIWebView.navigationDelegate = self ; |
| | | 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)webViewDidFinishLoad:(WKWebView *)webView{ |
| | | - (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation{ |
| | | |
| | | 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 - 600 * _scale, _height - 86 * _scale, 360 * _scale, 72 * _scale)]; |
| | | [m_CloseBtn setTitle:@"OK" 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]; |
| | | |
| | | UIView *view = UnityGetGLViewController().view; |
| | | [view addSubview:m_UIWebView]; |
| | | } |
| | | |
| | | |
| | | -(void)QuickSDKInit:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { |
| | | |
| | | UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; |
| | | |
| | | center.delegate=self; |
| | | [center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) |
| | | completionHandler:^(BOOL granted, NSError * _Nullable error) { |
| | | if( !error ) { |
| | | dispatch_async(dispatch_get_main_queue(), ^{ |
| | | [[UIApplication sharedApplication] registerForRemoteNotifications]; |
| | | }); |
| | | } else { |
| | | NSLog( @"ERROR: %@ - %@", error.localizedFailureReason, error.localizedDescription ); |
| | | } |
| | | }]; |
| | | |
| | | [SohaSetting sohaSettings].setWindow = UnityGetMainWindow(); |
| | | [SohaSetting setBaseURL:BaseURLProduct]; |
| | | [Soha sohaInitWithGameDelegate:self |
| | | application:[UIApplication sharedApplication] |
| | | launchOptions:launchOptions |
| | | loginManually:NO |
| | | andSetLanguageTo:SohaSDKLanguageVietnam]; |
| | | [Soha showInAppPopupTracking]; |
| | | |
| | | initedState = 0; |
| | | [self PlatformInitFinished]; |
| | | |
| | | [Soha showInAppPopupTracking]; |
| | | } |
| | | |
| | | - (UIInterfaceOrientationMask)application:(UIApplication*)application supportedInterfaceOrientationsForWindow:(UIWindow*)window |
| | | { |
| | | // return UIInterfaceOrientationMaskAll; |
| | | // return UIInterfaceOrientationMaskPortrait; |
| | | return UIInterfaceOrientationMaskLandscape; |
| | | } |
| | | |
| | | - (BOOL)application:(UIApplication *)app |
| | | openURL:(NSURL *)url |
| | | options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options{ |
| | | return [Soha application:app |
| | | openURL:url |
| | | options:options]; |
| | | } |
| | | |
| | | - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler{ |
| | | return [Soha application:application |
| | | continueUserActivity:userActivity |
| | | restorationHandler:restorationHandler]; |
| | | } |
| | | |
| | | - (void)applicationDidEnterBackground:(UIApplication *)application |
| | | { |
| | | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. |
| | | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. |
| | | [Soha sohaHandleDidEnterBackground]; |
| | | } |
| | | |
| | | - (void)applicationWillEnterForeground:(UIApplication *)application |
| | | { |
| | | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. |
| | | [Soha sohaHandleDidEnterForeground]; |
| | | } |
| | | |
| | | - (void)applicationDidBecomeActive:(UIApplication *)application |
| | | { |
| | | /* |
| | | Need for facebook |
| | | */ |
| | | [Soha sohaHandleDidBecomeActive]; |
| | | } |
| | | |
| | | - (void)applicationWillTerminate:(UIApplication *)application |
| | | { |
| | | /* |
| | | Need for facebook |
| | | */ |
| | | [Soha sohaHandleWillTerminate]; |
| | | } |
| | | |
| | | |
| | | - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { |
| | | [Soha sohaPostDeviceToken:deviceToken]; |
| | | } |
| | | - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler{ |
| | | [Soha userNotificationCenter:center didReceiveNotificationResponse:response]; |
| | | } |
| | | - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler{ |
| | | [Soha userNotificationCenter:center willPresentNotification:notification]; |
| | | } |
| | | |
| | | - (void)PlatformInitFinished{ |
| | | NSLog(@"渠道初始化成功,初始化没有回调直接通知成功"); |
| | | initedState=1; |
| | | NSMutableDictionary *_dict = [NSMutableDictionary dictionaryWithObjectsAndKeys: |
| | | [NSNumber numberWithInt:S2U_SdkInitComplete], @"code", |
| | | @"sohagame", @"channelPlatform", nil]; |
| | | [self SendMessageToUnity:_dict]; |
| | | } |
| | | |
| | | - (void)sohaLoginDelegate:(SohaUser *)user{ |
| | | if(user){ |
| | | NSLog(@"渠道登录成功"); |
| | | NSString *account = [SohaUser currentUser].userId; |
| | | NSString *game_id = @"1"; |
| | | NSString *session_id = [SohaUser currentUser].accessToken; |
| | | |
| | | NSDictionary *_dict = [NSDictionary dictionaryWithObjectsAndKeys: |
| | | [NSDictionary dictionaryWithObjectsAndKeys:account, @"account", |
| | | game_id, @"game_id", |
| | | session_id, @"session_id", nil],@"info", |
| | | [NSNumber numberWithInt:S2U_FreePlatformLoginOk], @"code", nil]; |
| | | [self SendMessageToUnity:_dict]; |
| | | } |
| | | else |
| | | { |
| | | NSLog(@"渠道登录失败"); |
| | | } |
| | | } |
| | | |
| | | - (void)sohaLogoutDelegate:(SohaUser *)user{ |
| | | NSLog(@"渠道注销成功"); |
| | | NSDictionary *_dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:S2U_FreePlatformLogoutOk], @"code", nil]; |
| | | [self SendMessageToUnity:_dict]; |
| | | } |
| | | |
| | | - (void)sohaDidPurchaseFailed:(SohaTransaction *)transaction purchaseError:(NSString *)error { |
| | | NSLog(@"渠道支付失败"); |
| | | NSDictionary *_dict = [NSDictionary dictionaryWithObjectsAndKeys: |
| | | [NSNumber numberWithInt:S2U_FreePlatformPayFail], @"code", nil]; |
| | | [self SendMessageToUnity:_dict]; |
| | | } |
| | | |
| | | |
| | | - (void)sohaDidPurchaseSuccess:(SohaTransaction *)transaction { |
| | | NSLog(@"渠道支付成功"); |
| | | NSDictionary *_dict = [NSDictionary dictionaryWithObjectsAndKeys: |
| | | [NSNumber numberWithInt:S2U_FreePlatformPayOk], @"code", nil]; |
| | | [self SendMessageToUnity:_dict]; |
| | | } |
| | | |
| | | |
| | | |
| | | -(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) PlatformLogin{ |
| | | switch (initedState) { |
| | | case 0: |
| | | break; |
| | | case 1: |
| | | [Soha sohaLoginSDK]; |
| | | break; |
| | | case 2: |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | |
| | | -(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: |
| | | [self PlatformLogin]; |
| | | break; |
| | | case U2S_ShowAccountView: |
| | | { |
| | | |
| | | } |
| | | break; |
| | | case U2S_FreePlatformLogout: |
| | | { |
| | | [Soha sohaLogoutSDK]; |
| | | } |
| | | break; |
| | | case U2S_CompleteTutorial: |
| | | { |
| | | [Soha gameDidCompleteTutorial]; |
| | | } |
| | | break; |
| | | case U2S_CreateRole: |
| | | { |
| | | // 更新角色信息 |
| | | NSString *serverId = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"sid"]]; |
| | | NSString *serverName = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"serverName"]]; |
| | | NSString *gameRoleID = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"roleID"]]; |
| | | NSString *gameRoleName = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"roleName"]]; |
| | | NSString *gameUserLevel = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"level"]]; |
| | | |
| | | [Soha sendEventSetRoleName:gameRoleName roleID:gameRoleID |
| | | roleLevel:gameUserLevel serverName:serverName |
| | | serverID:serverId]; |
| | | [Soha sendEventCreateCharacter]; |
| | | break; |
| | | } |
| | | case U2S_RoleLogin: |
| | | { |
| | | // 更新角色信息 |
| | | NSString *serverId = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"sid"]]; |
| | | |
| | | NSString *serverName = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"serverName"]]; |
| | | NSString *gameRoleID = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"roleID"]]; |
| | | NSString *gameRoleName = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"roleName"]]; |
| | | NSString *gameUserLevel = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"level"]]; |
| | | |
| | | [Soha sendEventSetRoleName:gameRoleName roleID:gameRoleID |
| | | roleLevel:gameUserLevel serverName:serverName |
| | | serverID:serverId]; |
| | | |
| | | |
| | | [Soha getListProduct:^(NSArray *products, NSString *error) { |
| | | if(error != nil){ |
| | | NSLog(@"支付列表获取失败"); |
| | | return; |
| | | } |
| | | NSArray *paylist = [NSArray new]; |
| | | paylist = products; |
| | | NSInteger count = products.count; |
| | | |
| | | NSMutableArray *strArray = [NSMutableArray new]; |
| | | for (int i = 0; i < count; i++) |
| | | { |
| | | SohaIAPModel *iapModel = (SohaIAPModel *) [products objectAtIndex:i]; |
| | | |
| | | [strArray addObject:iapModel.order_info]; |
| | | } |
| | | |
| | | NSString *orderInfos = [strArray componentsJoinedByString:@"|"]; |
| | | |
| | | NSDictionary *_dict = [NSDictionary dictionaryWithObjectsAndKeys: |
| | | [NSNumber numberWithInt:OrderInfoCallBack], @"code", orderInfos, @"orderInfos", nil]; |
| | | |
| | | [self SendMessageToUnity:_dict]; |
| | | }]; |
| | | break; |
| | | } |
| | | |
| | | case U2S_RoleLevelUp: |
| | | { |
| | | // 更新角色信息 |
| | | NSString *serverId = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"sid"]]; |
| | | NSString *serverName = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"serverName"]]; |
| | | NSString *gameRoleID = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"roleID"]]; |
| | | NSString *gameRoleName = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"roleName"]]; |
| | | NSString *gameUserLevel = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"level"]]; |
| | | |
| | | [Soha sendEventSetRoleName:gameRoleName roleID:gameRoleID |
| | | roleLevel:gameUserLevel serverName:serverName |
| | | serverID:serverId]; |
| | | break; |
| | | } |
| | | case U2S_FreePlatformPay: |
| | | { |
| | | NSString *order_info = [NSString stringWithFormat:@"%@",[_dict objectForKey:@"cpInfo"]]; |
| | | |
| | | [Soha payProductShowLoadingWithID:order_info]; |
| | | 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+1); |
| | | } |
| | | 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; |
| | | } |