├── MacPcmDataPlayer ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ └── MainMenu.xib ├── DragView.h ├── DragView.m ├── Info.plist ├── Window.h ├── Window.m └── main.m ├── PcmDataPlayer.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── PcmDataPlayer ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Images.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── LaunchImage.launchimage │ │ └── Contents.json ├── Info.plist ├── ViewController.h ├── ViewController.m └── main.m ├── Player ├── AVAudioPlayer+PCM.h ├── AVAudioPlayer+PCM.m ├── AVAudioPlayer+Sample.h └── AVAudioPlayer+Sample.m ├── README.md ├── Sample └── pcmData └── Util ├── NSTimer+BlocksSupport.h └── NSTimer+BlocksSupport.m /MacPcmDataPlayer/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // MacPcmDataPlayer 4 | // 5 | // Created by Chengyin on 15/12/21. 6 | // Copyright © 2015年 Chengyin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : NSObject 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /MacPcmDataPlayer/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // MacPcmDataPlayer 4 | // 5 | // Created by Chengyin on 15/12/21. 6 | // Copyright © 2015年 Chengyin. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @property (weak) IBOutlet NSWindow *window; 14 | @end 15 | 16 | @implementation AppDelegate 17 | 18 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { 19 | // Insert code here to initialize your application 20 | } 21 | 22 | - (void)applicationWillTerminate:(NSNotification *)aNotification { 23 | // Insert code here to tear down your application 24 | } 25 | 26 | - (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag 27 | { 28 | [self.window makeKeyAndOrderFront:NSApp]; 29 | return YES; 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /MacPcmDataPlayer/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "16x16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "32x32-1.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "32x32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "64x64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "128x128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "256x256-1.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "256x256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "idiom" : "mac", 47 | "size" : "256x256", 48 | "scale" : "2x" 49 | }, 50 | { 51 | "idiom" : "mac", 52 | "size" : "512x512", 53 | "scale" : "1x" 54 | }, 55 | { 56 | "idiom" : "mac", 57 | "size" : "512x512", 58 | "scale" : "2x" 59 | } 60 | ], 61 | "info" : { 62 | "version" : 1, 63 | "author" : "xcode" 64 | } 65 | } -------------------------------------------------------------------------------- /MacPcmDataPlayer/Base.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | Default 540 | 541 | 542 | 543 | 544 | 545 | 546 | Left to Right 547 | 548 | 549 | 550 | 551 | 552 | 553 | Right to Left 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | Default 565 | 566 | 567 | 568 | 569 | 570 | 571 | Left to Right 572 | 573 | 574 | 575 | 576 | 577 | 578 | Right to Left 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 689 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | -------------------------------------------------------------------------------- /MacPcmDataPlayer/DragView.h: -------------------------------------------------------------------------------- 1 | // 2 | // DragView.h 3 | // PcmDataPlayer 4 | // 5 | // Created by Chengyin on 15/12/21. 6 | // Copyright © 2015年 Chengyin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class DragView; 12 | @protocol DragViewDelegate 13 | - (void)dragView:(DragView *)dragView receivedFile:(NSString *)file; 14 | @end 15 | 16 | @interface DragView : NSView 17 | @property (nonatomic,weak) id delegate; 18 | @end 19 | -------------------------------------------------------------------------------- /MacPcmDataPlayer/DragView.m: -------------------------------------------------------------------------------- 1 | // 2 | // DragView.m 3 | // PcmDataPlayer 4 | // 5 | // Created by Chengyin on 15/12/21. 6 | // Copyright © 2015年 Chengyin. All rights reserved. 7 | // 8 | 9 | #import "DragView.h" 10 | 11 | @implementation DragView 12 | 13 | - (instancetype)initWithFrame:(NSRect)frame 14 | { 15 | self = [super initWithFrame:frame]; 16 | if (self) 17 | { 18 | [self registerForDraggedTypes:@[NSFilenamesPboardType]]; 19 | } 20 | return self; 21 | } 22 | 23 | - (NSDragOperation)draggingEntered:(id)sender 24 | { 25 | NSMutableArray* draggedFiles = [[[sender draggingPasteboard] propertyListForType:NSFilenamesPboardType] mutableCopy]; 26 | if (draggedFiles.count > 0) 27 | { 28 | return NSDragOperationCopy; 29 | } 30 | return NSDragOperationNone; 31 | } 32 | 33 | - (BOOL)prepareForDragOperation:(id)sender 34 | { 35 | return YES; 36 | } 37 | 38 | - (BOOL)performDragOperation:(id)sender 39 | { 40 | NSMutableArray* draggedFiles = [[[sender draggingPasteboard] propertyListForType:NSFilenamesPboardType] mutableCopy]; 41 | if (draggedFiles.count > 0) 42 | { 43 | [self draggingExited:nil]; 44 | [_delegate dragView:self receivedFile:draggedFiles[0]]; 45 | return YES; 46 | } 47 | return NO; 48 | } 49 | 50 | #pragma mark - paste 51 | - (BOOL)performKeyEquivalent:(NSEvent *)theEvent 52 | { 53 | NSString * chars = [theEvent characters]; 54 | BOOL status = NO; 55 | if ([theEvent modifierFlags] & NSCommandKeyMask) 56 | { 57 | if ([chars isEqualTo:@"v"]) 58 | { 59 | [self paste]; 60 | status = YES; 61 | } 62 | } 63 | 64 | if (status) 65 | { 66 | return YES; 67 | } 68 | 69 | return [super performKeyEquivalent:theEvent]; 70 | } 71 | 72 | - (void)paste 73 | { 74 | id item = [[self class] lastestPasteBoardItem]; 75 | if ([item isKindOfClass:[NSURL class]]) 76 | { 77 | NSURL *url = item; 78 | if ([url isFileURL]) 79 | { 80 | [_delegate dragView:self receivedFile:[url path]]; 81 | } 82 | } 83 | } 84 | 85 | + (id)lastestPasteBoardItem 86 | { 87 | NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; 88 | NSArray *classes = [[NSArray alloc] initWithObjects:[NSURL class], [NSImage class],nil]; 89 | NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: 90 | [NSNumber numberWithBool:YES], NSPasteboardURLReadingFileURLsOnlyKey,nil]; 91 | NSArray *copiedItems = [pasteboard readObjectsForClasses:classes options:options]; 92 | if (copiedItems.count > 0) 93 | { 94 | id item = [copiedItems lastObject]; 95 | if ([item isKindOfClass:[NSURL class]]) 96 | { 97 | NSURL *url = item; 98 | if ([url isFileURL]) 99 | { 100 | item = [NSURL fileURLWithPath:[url path]]; 101 | } 102 | } 103 | return item; 104 | } 105 | return nil; 106 | } 107 | @end 108 | -------------------------------------------------------------------------------- /MacPcmDataPlayer/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSHumanReadableCopyright 28 | Copyright © 2015年 Chengyin. All rights reserved. 29 | NSMainNibFile 30 | MainMenu 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /MacPcmDataPlayer/Window.h: -------------------------------------------------------------------------------- 1 | // 2 | // Window.h 3 | // PcmDataPlayer 4 | // 5 | // Created by Chengyin on 15/12/21. 6 | // Copyright © 2015年 Chengyin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface Window : NSWindow 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /MacPcmDataPlayer/Window.m: -------------------------------------------------------------------------------- 1 | // 2 | // Window.m 3 | // PcmDataPlayer 4 | // 5 | // Created by Chengyin on 15/12/21. 6 | // Copyright © 2015年 Chengyin. All rights reserved. 7 | // 8 | 9 | #import "Window.h" 10 | #import "AVAudioPlayer+Sample.h" 11 | #import "NSTimer+BlocksSupport.h" 12 | #import "DragView.h" 13 | 14 | @interface Window () 15 | { 16 | @private 17 | AVAudioPlayer *_player; 18 | NSTimer *_timer; 19 | NSString *_path; 20 | DragView *_dragView; 21 | } 22 | @property (nonatomic,strong) IBOutlet NSButton *playOrPauseButton; 23 | @property (nonatomic,strong) IBOutlet NSSlider *progressSlider; 24 | @property (nonatomic,strong) IBOutlet NSTextField *label; 25 | @property (nonatomic,strong) NSString *path; 26 | @end 27 | 28 | @implementation Window 29 | 30 | - (void)dragView:(DragView *)dragView receivedFile:(NSString *)file 31 | { 32 | [self createPlayer:file]; 33 | [self play]; 34 | } 35 | 36 | - (void)awakeFromNib 37 | { 38 | _dragView = [[DragView alloc] initWithFrame:NSMakeRect(0, 0, self.contentView.frame.size.width, self.contentView.frame.size.height)]; 39 | _dragView.delegate = self; 40 | [self.contentView addSubview:_dragView]; 41 | 42 | [self createPlayer:[[NSBundle mainBundle] pathForResource:@"pcmData" ofType:nil]]; 43 | } 44 | 45 | - (void)setFrame:(NSRect)frameRect display:(BOOL)flag 46 | { 47 | [super setFrame:frameRect display:flag]; 48 | _dragView.frame = NSMakeRect(0, 0, self.contentView.frame.size.width, self.contentView.frame.size.height); 49 | } 50 | 51 | - (void)createPlayer:(NSString *)path 52 | { 53 | self.path = path; 54 | _player = [AVAudioPlayer sp_createPlayer:_path]; 55 | } 56 | 57 | - (void)play 58 | { 59 | [_player play]; 60 | [self handleStatusChanged]; 61 | } 62 | 63 | - (void)pause 64 | { 65 | [_player pause]; 66 | [self handleStatusChanged]; 67 | } 68 | 69 | - (void)stop 70 | { 71 | [_player stop]; 72 | _player.currentTime = 0; 73 | [self handleStatusChanged]; 74 | [self progressMove]; 75 | } 76 | 77 | - (void)handleStatusChanged 78 | { 79 | if (_player.playing) 80 | { 81 | [self.playOrPauseButton setTitle:@"Pause"]; 82 | [self startTimer]; 83 | 84 | } 85 | else 86 | { 87 | [self.playOrPauseButton setTitle:@"Play"]; 88 | [self stopTimer]; 89 | [self progressMove]; 90 | } 91 | } 92 | 93 | - (void)setPath:(NSString *)path 94 | { 95 | _path = path; 96 | [_label setStringValue:_path]; 97 | } 98 | 99 | #pragma mark - timer 100 | - (void)startTimer 101 | { 102 | if (!_timer) 103 | { 104 | __weak typeof(self)weakSelf = self; 105 | _timer = [NSTimer bs_scheduledTimerWithTimeInterval:1 block:^{ 106 | __strong __typeof(weakSelf)strongSelf = weakSelf; 107 | [strongSelf progressMove]; 108 | [strongSelf handleStatusChanged]; 109 | } repeats:YES]; 110 | [_timer fire]; 111 | } 112 | } 113 | 114 | - (void)stopTimer 115 | { 116 | if (_timer) 117 | { 118 | [_timer invalidate]; 119 | _timer = nil; 120 | } 121 | } 122 | 123 | - (void)progressMove 124 | { 125 | if (!self.progressSlider.isHighlighted) 126 | { 127 | if (_player.duration != 0) 128 | { 129 | self.progressSlider.doubleValue = _player.currentTime / _player.duration; 130 | } 131 | else 132 | { 133 | self.progressSlider.doubleValue = 0; 134 | } 135 | } 136 | } 137 | 138 | #pragma mark - action 139 | - (IBAction)playOrPause:(id)sender 140 | { 141 | if (_player.playing) 142 | { 143 | [self pause]; 144 | } 145 | else 146 | { 147 | [self play]; 148 | } 149 | } 150 | 151 | - (IBAction)stop:(id)sender 152 | { 153 | [self stop]; 154 | } 155 | 156 | - (IBAction)seek:(id)sender 157 | { 158 | _player.currentTime = _player.duration * self.progressSlider.doubleValue; 159 | } 160 | @end 161 | -------------------------------------------------------------------------------- /MacPcmDataPlayer/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // MacPcmDataPlayer 4 | // 5 | // Created by Chengyin on 15/12/21. 6 | // Copyright © 2015年 Chengyin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, const char * argv[]) { 12 | return NSApplicationMain(argc, argv); 13 | } 14 | -------------------------------------------------------------------------------- /PcmDataPlayer.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | DE2EB3211C27D9330037F49A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DE2EB3201C27D9330037F49A /* AppDelegate.m */; }; 11 | DE2EB3241C27D9330037F49A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DE2EB3231C27D9330037F49A /* main.m */; }; 12 | DE2EB3261C27D9330037F49A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DE2EB3251C27D9330037F49A /* Assets.xcassets */; }; 13 | DE2EB3291C27D9330037F49A /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = DE2EB3271C27D9330037F49A /* MainMenu.xib */; }; 14 | DE2EB3731C27DE360037F49A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DE2EB3721C27DE360037F49A /* main.m */; }; 15 | DE2EB3761C27DE360037F49A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DE2EB3751C27DE360037F49A /* AppDelegate.m */; }; 16 | DE2EB3791C27DE360037F49A /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DE2EB3781C27DE360037F49A /* ViewController.m */; }; 17 | DE2EB37C1C27DE360037F49A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DE2EB37A1C27DE360037F49A /* Main.storyboard */; }; 18 | DE2EB37E1C27DE360037F49A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DE2EB37D1C27DE360037F49A /* Assets.xcassets */; }; 19 | DE2EB3811C27DE360037F49A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DE2EB37F1C27DE360037F49A /* LaunchScreen.storyboard */; }; 20 | DE2EB3861C27DEC20037F49A /* AVAudioPlayer+PCM.m in Sources */ = {isa = PBXBuildFile; fileRef = DE2EB3301C27D95F0037F49A /* AVAudioPlayer+PCM.m */; }; 21 | DE2EB3871C27DEC20037F49A /* AVAudioPlayer+PCM.m in Sources */ = {isa = PBXBuildFile; fileRef = DE2EB3301C27D95F0037F49A /* AVAudioPlayer+PCM.m */; }; 22 | DE2EB3881C27DEEA0037F49A /* pcmData in Resources */ = {isa = PBXBuildFile; fileRef = DE2EB3321C27D95F0037F49A /* pcmData */; }; 23 | DE2EB3891C27DEEB0037F49A /* pcmData in Resources */ = {isa = PBXBuildFile; fileRef = DE2EB3321C27D95F0037F49A /* pcmData */; }; 24 | DE2EB38D1C27E0D50037F49A /* NSTimer+BlocksSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = DE2EB38C1C27E0D50037F49A /* NSTimer+BlocksSupport.m */; }; 25 | DE2EB38E1C27E0D50037F49A /* NSTimer+BlocksSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = DE2EB38C1C27E0D50037F49A /* NSTimer+BlocksSupport.m */; }; 26 | DE2EB3911C27EAAD0037F49A /* Window.m in Sources */ = {isa = PBXBuildFile; fileRef = DE2EB3901C27EAAD0037F49A /* Window.m */; }; 27 | DE2EB3941C27ECB70037F49A /* AVAudioPlayer+Sample.m in Sources */ = {isa = PBXBuildFile; fileRef = DE2EB3931C27ECB70037F49A /* AVAudioPlayer+Sample.m */; }; 28 | DE2EB3971C28009B0037F49A /* DragView.m in Sources */ = {isa = PBXBuildFile; fileRef = DE2EB3961C28009B0037F49A /* DragView.m */; }; 29 | /* End PBXBuildFile section */ 30 | 31 | /* Begin PBXFileReference section */ 32 | DE2EB31D1C27D9330037F49A /* MacPcmDataPlayer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MacPcmDataPlayer.app; sourceTree = BUILT_PRODUCTS_DIR; }; 33 | DE2EB31F1C27D9330037F49A /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 34 | DE2EB3201C27D9330037F49A /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 35 | DE2EB3231C27D9330037F49A /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 36 | DE2EB3251C27D9330037F49A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 37 | DE2EB3281C27D9330037F49A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; 38 | DE2EB32A1C27D9330037F49A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 39 | DE2EB32F1C27D95F0037F49A /* AVAudioPlayer+PCM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "AVAudioPlayer+PCM.h"; sourceTree = ""; }; 40 | DE2EB3301C27D95F0037F49A /* AVAudioPlayer+PCM.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "AVAudioPlayer+PCM.m"; sourceTree = ""; }; 41 | DE2EB3321C27D95F0037F49A /* pcmData */ = {isa = PBXFileReference; lastKnownFileType = file; path = pcmData; sourceTree = ""; }; 42 | DE2EB36F1C27DE360037F49A /* PcmDataPlayer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PcmDataPlayer.app; sourceTree = BUILT_PRODUCTS_DIR; }; 43 | DE2EB3721C27DE360037F49A /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 44 | DE2EB3741C27DE360037F49A /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 45 | DE2EB3751C27DE360037F49A /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 46 | DE2EB3771C27DE360037F49A /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 47 | DE2EB3781C27DE360037F49A /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 48 | DE2EB37B1C27DE360037F49A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 49 | DE2EB37D1C27DE360037F49A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 50 | DE2EB3801C27DE360037F49A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 51 | DE2EB3821C27DE360037F49A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 52 | DE2EB38B1C27E0D50037F49A /* NSTimer+BlocksSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSTimer+BlocksSupport.h"; sourceTree = ""; }; 53 | DE2EB38C1C27E0D50037F49A /* NSTimer+BlocksSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSTimer+BlocksSupport.m"; sourceTree = ""; }; 54 | DE2EB38F1C27EAAD0037F49A /* Window.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Window.h; sourceTree = ""; }; 55 | DE2EB3901C27EAAD0037F49A /* Window.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Window.m; sourceTree = ""; }; 56 | DE2EB3921C27ECB70037F49A /* AVAudioPlayer+Sample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "AVAudioPlayer+Sample.h"; sourceTree = ""; }; 57 | DE2EB3931C27ECB70037F49A /* AVAudioPlayer+Sample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "AVAudioPlayer+Sample.m"; sourceTree = ""; }; 58 | DE2EB3951C28009B0037F49A /* DragView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DragView.h; sourceTree = ""; }; 59 | DE2EB3961C28009B0037F49A /* DragView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DragView.m; sourceTree = ""; }; 60 | /* End PBXFileReference section */ 61 | 62 | /* Begin PBXFrameworksBuildPhase section */ 63 | DE2EB31A1C27D9330037F49A /* Frameworks */ = { 64 | isa = PBXFrameworksBuildPhase; 65 | buildActionMask = 2147483647; 66 | files = ( 67 | ); 68 | runOnlyForDeploymentPostprocessing = 0; 69 | }; 70 | DE2EB36C1C27DE360037F49A /* Frameworks */ = { 71 | isa = PBXFrameworksBuildPhase; 72 | buildActionMask = 2147483647; 73 | files = ( 74 | ); 75 | runOnlyForDeploymentPostprocessing = 0; 76 | }; 77 | /* End PBXFrameworksBuildPhase section */ 78 | 79 | /* Begin PBXGroup section */ 80 | DE2EB31E1C27D9330037F49A /* MacPcmDataPlayer */ = { 81 | isa = PBXGroup; 82 | children = ( 83 | DE2EB38F1C27EAAD0037F49A /* Window.h */, 84 | DE2EB3901C27EAAD0037F49A /* Window.m */, 85 | DE2EB3951C28009B0037F49A /* DragView.h */, 86 | DE2EB3961C28009B0037F49A /* DragView.m */, 87 | DE2EB31F1C27D9330037F49A /* AppDelegate.h */, 88 | DE2EB3201C27D9330037F49A /* AppDelegate.m */, 89 | DE2EB3251C27D9330037F49A /* Assets.xcassets */, 90 | DE2EB3271C27D9330037F49A /* MainMenu.xib */, 91 | DE2EB32A1C27D9330037F49A /* Info.plist */, 92 | DE2EB3221C27D9330037F49A /* Supporting Files */, 93 | ); 94 | path = MacPcmDataPlayer; 95 | sourceTree = ""; 96 | }; 97 | DE2EB3221C27D9330037F49A /* Supporting Files */ = { 98 | isa = PBXGroup; 99 | children = ( 100 | DE2EB3231C27D9330037F49A /* main.m */, 101 | ); 102 | name = "Supporting Files"; 103 | sourceTree = ""; 104 | }; 105 | DE2EB32E1C27D95F0037F49A /* Player */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | DE2EB32F1C27D95F0037F49A /* AVAudioPlayer+PCM.h */, 109 | DE2EB3301C27D95F0037F49A /* AVAudioPlayer+PCM.m */, 110 | DE2EB3921C27ECB70037F49A /* AVAudioPlayer+Sample.h */, 111 | DE2EB3931C27ECB70037F49A /* AVAudioPlayer+Sample.m */, 112 | ); 113 | path = Player; 114 | sourceTree = ""; 115 | }; 116 | DE2EB3311C27D95F0037F49A /* Sample */ = { 117 | isa = PBXGroup; 118 | children = ( 119 | DE2EB3321C27D95F0037F49A /* pcmData */, 120 | ); 121 | path = Sample; 122 | sourceTree = ""; 123 | }; 124 | DE2EB3701C27DE360037F49A /* PcmDataPlayer */ = { 125 | isa = PBXGroup; 126 | children = ( 127 | DE2EB3741C27DE360037F49A /* AppDelegate.h */, 128 | DE2EB3751C27DE360037F49A /* AppDelegate.m */, 129 | DE2EB3771C27DE360037F49A /* ViewController.h */, 130 | DE2EB3781C27DE360037F49A /* ViewController.m */, 131 | DE2EB37A1C27DE360037F49A /* Main.storyboard */, 132 | DE2EB37D1C27DE360037F49A /* Assets.xcassets */, 133 | DE2EB37F1C27DE360037F49A /* LaunchScreen.storyboard */, 134 | DE2EB3821C27DE360037F49A /* Info.plist */, 135 | DE2EB3711C27DE360037F49A /* Supporting Files */, 136 | ); 137 | path = PcmDataPlayer; 138 | sourceTree = ""; 139 | }; 140 | DE2EB3711C27DE360037F49A /* Supporting Files */ = { 141 | isa = PBXGroup; 142 | children = ( 143 | DE2EB3721C27DE360037F49A /* main.m */, 144 | ); 145 | name = "Supporting Files"; 146 | sourceTree = ""; 147 | }; 148 | DE2EB38A1C27E0D50037F49A /* Util */ = { 149 | isa = PBXGroup; 150 | children = ( 151 | DE2EB38B1C27E0D50037F49A /* NSTimer+BlocksSupport.h */, 152 | DE2EB38C1C27E0D50037F49A /* NSTimer+BlocksSupport.m */, 153 | ); 154 | path = Util; 155 | sourceTree = ""; 156 | }; 157 | DE4EE5DB1A4BB78300852DC3 = { 158 | isa = PBXGroup; 159 | children = ( 160 | DE2EB32E1C27D95F0037F49A /* Player */, 161 | DE2EB3311C27D95F0037F49A /* Sample */, 162 | DE2EB38A1C27E0D50037F49A /* Util */, 163 | DE2EB31E1C27D9330037F49A /* MacPcmDataPlayer */, 164 | DE2EB3701C27DE360037F49A /* PcmDataPlayer */, 165 | DE4EE5E51A4BB78300852DC3 /* Products */, 166 | ); 167 | sourceTree = ""; 168 | }; 169 | DE4EE5E51A4BB78300852DC3 /* Products */ = { 170 | isa = PBXGroup; 171 | children = ( 172 | DE2EB31D1C27D9330037F49A /* MacPcmDataPlayer.app */, 173 | DE2EB36F1C27DE360037F49A /* PcmDataPlayer.app */, 174 | ); 175 | name = Products; 176 | sourceTree = ""; 177 | }; 178 | /* End PBXGroup section */ 179 | 180 | /* Begin PBXNativeTarget section */ 181 | DE2EB31C1C27D9330037F49A /* MacPcmDataPlayer */ = { 182 | isa = PBXNativeTarget; 183 | buildConfigurationList = DE2EB32D1C27D9330037F49A /* Build configuration list for PBXNativeTarget "MacPcmDataPlayer" */; 184 | buildPhases = ( 185 | DE2EB3191C27D9330037F49A /* Sources */, 186 | DE2EB31A1C27D9330037F49A /* Frameworks */, 187 | DE2EB31B1C27D9330037F49A /* Resources */, 188 | ); 189 | buildRules = ( 190 | ); 191 | dependencies = ( 192 | ); 193 | name = MacPcmDataPlayer; 194 | productName = MacPcmDataPlayer; 195 | productReference = DE2EB31D1C27D9330037F49A /* MacPcmDataPlayer.app */; 196 | productType = "com.apple.product-type.application"; 197 | }; 198 | DE2EB36E1C27DE360037F49A /* PcmDataPlayer */ = { 199 | isa = PBXNativeTarget; 200 | buildConfigurationList = DE2EB3831C27DE360037F49A /* Build configuration list for PBXNativeTarget "PcmDataPlayer" */; 201 | buildPhases = ( 202 | DE2EB36B1C27DE360037F49A /* Sources */, 203 | DE2EB36C1C27DE360037F49A /* Frameworks */, 204 | DE2EB36D1C27DE360037F49A /* Resources */, 205 | ); 206 | buildRules = ( 207 | ); 208 | dependencies = ( 209 | ); 210 | name = PcmDataPlayer; 211 | productName = PcmDataPlayer; 212 | productReference = DE2EB36F1C27DE360037F49A /* PcmDataPlayer.app */; 213 | productType = "com.apple.product-type.application"; 214 | }; 215 | /* End PBXNativeTarget section */ 216 | 217 | /* Begin PBXProject section */ 218 | DE4EE5DC1A4BB78300852DC3 /* Project object */ = { 219 | isa = PBXProject; 220 | attributes = { 221 | LastUpgradeCheck = 0720; 222 | ORGANIZATIONNAME = Chengyin; 223 | TargetAttributes = { 224 | DE2EB31C1C27D9330037F49A = { 225 | CreatedOnToolsVersion = 7.2; 226 | }; 227 | DE2EB36E1C27DE360037F49A = { 228 | CreatedOnToolsVersion = 7.2; 229 | }; 230 | }; 231 | }; 232 | buildConfigurationList = DE4EE5DF1A4BB78300852DC3 /* Build configuration list for PBXProject "PcmDataPlayer" */; 233 | compatibilityVersion = "Xcode 3.2"; 234 | developmentRegion = English; 235 | hasScannedForEncodings = 0; 236 | knownRegions = ( 237 | en, 238 | Base, 239 | ); 240 | mainGroup = DE4EE5DB1A4BB78300852DC3; 241 | productRefGroup = DE4EE5E51A4BB78300852DC3 /* Products */; 242 | projectDirPath = ""; 243 | projectRoot = ""; 244 | targets = ( 245 | DE2EB36E1C27DE360037F49A /* PcmDataPlayer */, 246 | DE2EB31C1C27D9330037F49A /* MacPcmDataPlayer */, 247 | ); 248 | }; 249 | /* End PBXProject section */ 250 | 251 | /* Begin PBXResourcesBuildPhase section */ 252 | DE2EB31B1C27D9330037F49A /* Resources */ = { 253 | isa = PBXResourcesBuildPhase; 254 | buildActionMask = 2147483647; 255 | files = ( 256 | DE2EB3881C27DEEA0037F49A /* pcmData in Resources */, 257 | DE2EB3261C27D9330037F49A /* Assets.xcassets in Resources */, 258 | DE2EB3291C27D9330037F49A /* MainMenu.xib in Resources */, 259 | ); 260 | runOnlyForDeploymentPostprocessing = 0; 261 | }; 262 | DE2EB36D1C27DE360037F49A /* Resources */ = { 263 | isa = PBXResourcesBuildPhase; 264 | buildActionMask = 2147483647; 265 | files = ( 266 | DE2EB3811C27DE360037F49A /* LaunchScreen.storyboard in Resources */, 267 | DE2EB3891C27DEEB0037F49A /* pcmData in Resources */, 268 | DE2EB37E1C27DE360037F49A /* Assets.xcassets in Resources */, 269 | DE2EB37C1C27DE360037F49A /* Main.storyboard in Resources */, 270 | ); 271 | runOnlyForDeploymentPostprocessing = 0; 272 | }; 273 | /* End PBXResourcesBuildPhase section */ 274 | 275 | /* Begin PBXSourcesBuildPhase section */ 276 | DE2EB3191C27D9330037F49A /* Sources */ = { 277 | isa = PBXSourcesBuildPhase; 278 | buildActionMask = 2147483647; 279 | files = ( 280 | DE2EB3861C27DEC20037F49A /* AVAudioPlayer+PCM.m in Sources */, 281 | DE2EB3241C27D9330037F49A /* main.m in Sources */, 282 | DE2EB38E1C27E0D50037F49A /* NSTimer+BlocksSupport.m in Sources */, 283 | DE2EB3971C28009B0037F49A /* DragView.m in Sources */, 284 | DE2EB3211C27D9330037F49A /* AppDelegate.m in Sources */, 285 | DE2EB3941C27ECB70037F49A /* AVAudioPlayer+Sample.m in Sources */, 286 | DE2EB3911C27EAAD0037F49A /* Window.m in Sources */, 287 | ); 288 | runOnlyForDeploymentPostprocessing = 0; 289 | }; 290 | DE2EB36B1C27DE360037F49A /* Sources */ = { 291 | isa = PBXSourcesBuildPhase; 292 | buildActionMask = 2147483647; 293 | files = ( 294 | DE2EB38D1C27E0D50037F49A /* NSTimer+BlocksSupport.m in Sources */, 295 | DE2EB3791C27DE360037F49A /* ViewController.m in Sources */, 296 | DE2EB3761C27DE360037F49A /* AppDelegate.m in Sources */, 297 | DE2EB3731C27DE360037F49A /* main.m in Sources */, 298 | DE2EB3871C27DEC20037F49A /* AVAudioPlayer+PCM.m in Sources */, 299 | ); 300 | runOnlyForDeploymentPostprocessing = 0; 301 | }; 302 | /* End PBXSourcesBuildPhase section */ 303 | 304 | /* Begin PBXVariantGroup section */ 305 | DE2EB3271C27D9330037F49A /* MainMenu.xib */ = { 306 | isa = PBXVariantGroup; 307 | children = ( 308 | DE2EB3281C27D9330037F49A /* Base */, 309 | ); 310 | name = MainMenu.xib; 311 | sourceTree = ""; 312 | }; 313 | DE2EB37A1C27DE360037F49A /* Main.storyboard */ = { 314 | isa = PBXVariantGroup; 315 | children = ( 316 | DE2EB37B1C27DE360037F49A /* Base */, 317 | ); 318 | name = Main.storyboard; 319 | sourceTree = ""; 320 | }; 321 | DE2EB37F1C27DE360037F49A /* LaunchScreen.storyboard */ = { 322 | isa = PBXVariantGroup; 323 | children = ( 324 | DE2EB3801C27DE360037F49A /* Base */, 325 | ); 326 | name = LaunchScreen.storyboard; 327 | sourceTree = ""; 328 | }; 329 | /* End PBXVariantGroup section */ 330 | 331 | /* Begin XCBuildConfiguration section */ 332 | DE2EB32B1C27D9330037F49A /* Debug */ = { 333 | isa = XCBuildConfiguration; 334 | buildSettings = { 335 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 336 | CODE_SIGN_IDENTITY = "-"; 337 | COMBINE_HIDPI_IMAGES = YES; 338 | DEBUG_INFORMATION_FORMAT = dwarf; 339 | ENABLE_TESTABILITY = YES; 340 | GCC_NO_COMMON_BLOCKS = YES; 341 | INFOPLIST_FILE = MacPcmDataPlayer/Info.plist; 342 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 343 | MACOSX_DEPLOYMENT_TARGET = 10.8; 344 | PRODUCT_BUNDLE_IDENTIFIER = com.mycompany.MacPcmDataPlayer; 345 | PRODUCT_NAME = "$(TARGET_NAME)"; 346 | SDKROOT = macosx; 347 | }; 348 | name = Debug; 349 | }; 350 | DE2EB32C1C27D9330037F49A /* Release */ = { 351 | isa = XCBuildConfiguration; 352 | buildSettings = { 353 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 354 | CODE_SIGN_IDENTITY = "-"; 355 | COMBINE_HIDPI_IMAGES = YES; 356 | COPY_PHASE_STRIP = NO; 357 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 358 | GCC_NO_COMMON_BLOCKS = YES; 359 | INFOPLIST_FILE = MacPcmDataPlayer/Info.plist; 360 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 361 | MACOSX_DEPLOYMENT_TARGET = 10.8; 362 | PRODUCT_BUNDLE_IDENTIFIER = com.mycompany.MacPcmDataPlayer; 363 | PRODUCT_NAME = "$(TARGET_NAME)"; 364 | SDKROOT = macosx; 365 | }; 366 | name = Release; 367 | }; 368 | DE2EB3841C27DE360037F49A /* Debug */ = { 369 | isa = XCBuildConfiguration; 370 | buildSettings = { 371 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 372 | DEBUG_INFORMATION_FORMAT = dwarf; 373 | GCC_NO_COMMON_BLOCKS = YES; 374 | INFOPLIST_FILE = PcmDataPlayer/Info.plist; 375 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 376 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 377 | PRODUCT_BUNDLE_IDENTIFIER = com.mycompany.PcmDataPlayer; 378 | PRODUCT_NAME = "$(TARGET_NAME)"; 379 | TARGETED_DEVICE_FAMILY = 1; 380 | }; 381 | name = Debug; 382 | }; 383 | DE2EB3851C27DE360037F49A /* Release */ = { 384 | isa = XCBuildConfiguration; 385 | buildSettings = { 386 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 387 | COPY_PHASE_STRIP = NO; 388 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 389 | GCC_NO_COMMON_BLOCKS = YES; 390 | INFOPLIST_FILE = PcmDataPlayer/Info.plist; 391 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 392 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 393 | PRODUCT_BUNDLE_IDENTIFIER = com.mycompany.PcmDataPlayer; 394 | PRODUCT_NAME = "$(TARGET_NAME)"; 395 | TARGETED_DEVICE_FAMILY = 1; 396 | }; 397 | name = Release; 398 | }; 399 | DE4EE6051A4BB78300852DC3 /* Debug */ = { 400 | isa = XCBuildConfiguration; 401 | buildSettings = { 402 | ALWAYS_SEARCH_USER_PATHS = NO; 403 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 404 | CLANG_CXX_LIBRARY = "libc++"; 405 | CLANG_ENABLE_MODULES = YES; 406 | CLANG_ENABLE_OBJC_ARC = YES; 407 | CLANG_WARN_BOOL_CONVERSION = YES; 408 | CLANG_WARN_CONSTANT_CONVERSION = YES; 409 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 410 | CLANG_WARN_EMPTY_BODY = YES; 411 | CLANG_WARN_ENUM_CONVERSION = YES; 412 | CLANG_WARN_INT_CONVERSION = YES; 413 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 414 | CLANG_WARN_UNREACHABLE_CODE = YES; 415 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 416 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 417 | COPY_PHASE_STRIP = NO; 418 | ENABLE_STRICT_OBJC_MSGSEND = YES; 419 | ENABLE_TESTABILITY = YES; 420 | GCC_C_LANGUAGE_STANDARD = gnu99; 421 | GCC_DYNAMIC_NO_PIC = NO; 422 | GCC_OPTIMIZATION_LEVEL = 0; 423 | GCC_PREPROCESSOR_DEFINITIONS = ( 424 | "DEBUG=1", 425 | "$(inherited)", 426 | ); 427 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 428 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 429 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 430 | GCC_WARN_UNDECLARED_SELECTOR = YES; 431 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 432 | GCC_WARN_UNUSED_FUNCTION = YES; 433 | GCC_WARN_UNUSED_VARIABLE = YES; 434 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 435 | MTL_ENABLE_DEBUG_INFO = YES; 436 | ONLY_ACTIVE_ARCH = YES; 437 | SDKROOT = iphoneos; 438 | }; 439 | name = Debug; 440 | }; 441 | DE4EE6061A4BB78300852DC3 /* Release */ = { 442 | isa = XCBuildConfiguration; 443 | buildSettings = { 444 | ALWAYS_SEARCH_USER_PATHS = NO; 445 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 446 | CLANG_CXX_LIBRARY = "libc++"; 447 | CLANG_ENABLE_MODULES = YES; 448 | CLANG_ENABLE_OBJC_ARC = YES; 449 | CLANG_WARN_BOOL_CONVERSION = YES; 450 | CLANG_WARN_CONSTANT_CONVERSION = YES; 451 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 452 | CLANG_WARN_EMPTY_BODY = YES; 453 | CLANG_WARN_ENUM_CONVERSION = YES; 454 | CLANG_WARN_INT_CONVERSION = YES; 455 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 456 | CLANG_WARN_UNREACHABLE_CODE = YES; 457 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 458 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 459 | COPY_PHASE_STRIP = YES; 460 | ENABLE_NS_ASSERTIONS = NO; 461 | ENABLE_STRICT_OBJC_MSGSEND = YES; 462 | GCC_C_LANGUAGE_STANDARD = gnu99; 463 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 464 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 465 | GCC_WARN_UNDECLARED_SELECTOR = YES; 466 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 467 | GCC_WARN_UNUSED_FUNCTION = YES; 468 | GCC_WARN_UNUSED_VARIABLE = YES; 469 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 470 | MTL_ENABLE_DEBUG_INFO = NO; 471 | SDKROOT = iphoneos; 472 | VALIDATE_PRODUCT = YES; 473 | }; 474 | name = Release; 475 | }; 476 | /* End XCBuildConfiguration section */ 477 | 478 | /* Begin XCConfigurationList section */ 479 | DE2EB32D1C27D9330037F49A /* Build configuration list for PBXNativeTarget "MacPcmDataPlayer" */ = { 480 | isa = XCConfigurationList; 481 | buildConfigurations = ( 482 | DE2EB32B1C27D9330037F49A /* Debug */, 483 | DE2EB32C1C27D9330037F49A /* Release */, 484 | ); 485 | defaultConfigurationIsVisible = 0; 486 | defaultConfigurationName = Release; 487 | }; 488 | DE2EB3831C27DE360037F49A /* Build configuration list for PBXNativeTarget "PcmDataPlayer" */ = { 489 | isa = XCConfigurationList; 490 | buildConfigurations = ( 491 | DE2EB3841C27DE360037F49A /* Debug */, 492 | DE2EB3851C27DE360037F49A /* Release */, 493 | ); 494 | defaultConfigurationIsVisible = 0; 495 | defaultConfigurationName = Release; 496 | }; 497 | DE4EE5DF1A4BB78300852DC3 /* Build configuration list for PBXProject "PcmDataPlayer" */ = { 498 | isa = XCConfigurationList; 499 | buildConfigurations = ( 500 | DE4EE6051A4BB78300852DC3 /* Debug */, 501 | DE4EE6061A4BB78300852DC3 /* Release */, 502 | ); 503 | defaultConfigurationIsVisible = 0; 504 | defaultConfigurationName = Release; 505 | }; 506 | /* End XCConfigurationList section */ 507 | }; 508 | rootObject = DE4EE5DC1A4BB78300852DC3 /* Project object */; 509 | } 510 | -------------------------------------------------------------------------------- /PcmDataPlayer.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /PcmDataPlayer/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // PcmDataPlayer 4 | // 5 | // Created by Chengyin on 14-12-25. 6 | // Copyright (c) 2014年 Chengyin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /PcmDataPlayer/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // PcmDataPlayer 4 | // 5 | // Created by Chengyin on 14-12-25. 6 | // Copyright (c) 2014年 Chengyin. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | - (void)applicationWillResignActive:(UIApplication *)application { 24 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 26 | } 27 | 28 | - (void)applicationDidEnterBackground:(UIApplication *)application { 29 | // 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. 30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 31 | } 32 | 33 | - (void)applicationWillEnterForeground:(UIApplication *)application { 34 | // 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. 35 | } 36 | 37 | - (void)applicationDidBecomeActive:(UIApplication *)application { 38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application { 42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /PcmDataPlayer/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "83.5x83.5", 66 | "scale" : "2x" 67 | } 68 | ], 69 | "info" : { 70 | "version" : 1, 71 | "author" : "xcode" 72 | } 73 | } -------------------------------------------------------------------------------- /PcmDataPlayer/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /PcmDataPlayer/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 29 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /PcmDataPlayer/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /PcmDataPlayer/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "minimum-system-version" : "7.0", 7 | "subtype" : "retina4", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "idiom" : "iphone", 12 | "scale" : "1x", 13 | "orientation" : "portrait" 14 | }, 15 | { 16 | "idiom" : "iphone", 17 | "scale" : "2x", 18 | "orientation" : "portrait" 19 | }, 20 | { 21 | "orientation" : "portrait", 22 | "idiom" : "iphone", 23 | "subtype" : "retina4", 24 | "scale" : "2x" 25 | }, 26 | { 27 | "orientation" : "portrait", 28 | "idiom" : "iphone", 29 | "minimum-system-version" : "7.0", 30 | "scale" : "2x" 31 | } 32 | ], 33 | "info" : { 34 | "version" : 1, 35 | "author" : "xcode" 36 | } 37 | } -------------------------------------------------------------------------------- /PcmDataPlayer/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /PcmDataPlayer/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // PcmDataPlayer 4 | // 5 | // Created by Chengyin on 14-12-25. 6 | // Copyright (c) 2014年 Chengyin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | @end 14 | 15 | -------------------------------------------------------------------------------- /PcmDataPlayer/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // PcmDataPlayer 4 | // 5 | // Created by Chengyin on 14-12-25. 6 | // Copyright (c) 2014年 Chengyin. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "AVAudioPlayer+Sample.h" 11 | #import "NSTimer+BlocksSupport.h" 12 | 13 | @interface ViewController () 14 | { 15 | @private 16 | AVAudioPlayer *_player; 17 | NSTimer *_timer; 18 | NSString *_path; 19 | } 20 | @property (nonatomic,strong) IBOutlet UIButton *playOrPauseButton; 21 | @property (nonatomic,strong) IBOutlet UISlider *progressSlider; 22 | @end 23 | 24 | @implementation ViewController 25 | 26 | - (void)viewDidLoad 27 | { 28 | [super viewDidLoad]; 29 | // Do any additional setup after loading the view, typically from a nib. 30 | 31 | _path = [[NSBundle mainBundle] pathForResource:@"pcmData" ofType:nil]; 32 | _player = [AVAudioPlayer sp_createPlayer:_path]; 33 | [self play]; 34 | } 35 | 36 | 37 | #pragma mark - player 38 | - (void)play 39 | { 40 | [_player play]; 41 | [self handleStatusChanged]; 42 | } 43 | 44 | - (void)pause 45 | { 46 | [_player pause]; 47 | [self handleStatusChanged]; 48 | } 49 | 50 | - (void)stop 51 | { 52 | [_player stop]; 53 | _player.currentTime = 0; 54 | [self handleStatusChanged]; 55 | [self progressMove]; 56 | } 57 | 58 | - (void)handleStatusChanged 59 | { 60 | if (_player.playing) 61 | { 62 | [self.playOrPauseButton setTitle:@"Pause" forState:UIControlStateNormal]; 63 | [self startTimer]; 64 | 65 | } 66 | else 67 | { 68 | [self.playOrPauseButton setTitle:@"Play" forState:UIControlStateNormal]; 69 | [self stopTimer]; 70 | [self progressMove]; 71 | } 72 | } 73 | 74 | #pragma mark - timer 75 | - (void)startTimer 76 | { 77 | if (!_timer) 78 | { 79 | __weak typeof(self)weakSelf = self; 80 | _timer = [NSTimer bs_scheduledTimerWithTimeInterval:1 block:^{ 81 | __strong __typeof(weakSelf)strongSelf = weakSelf; 82 | [strongSelf progressMove]; 83 | [strongSelf handleStatusChanged]; 84 | } repeats:YES]; 85 | [_timer fire]; 86 | } 87 | } 88 | 89 | - (void)stopTimer 90 | { 91 | if (_timer) 92 | { 93 | [_timer invalidate]; 94 | _timer = nil; 95 | } 96 | } 97 | 98 | - (void)progressMove 99 | { 100 | if (!self.progressSlider.tracking) 101 | { 102 | if (_player.duration != 0) 103 | { 104 | self.progressSlider.value = _player.currentTime / _player.duration; 105 | } 106 | else 107 | { 108 | self.progressSlider.value = 0; 109 | } 110 | } 111 | } 112 | 113 | #pragma mark - action 114 | - (IBAction)playOrPause:(id)sender 115 | { 116 | if (_player.playing) 117 | { 118 | [self pause]; 119 | } 120 | else 121 | { 122 | [self play]; 123 | } 124 | } 125 | 126 | - (IBAction)stop:(id)sender 127 | { 128 | [self stop]; 129 | } 130 | 131 | - (IBAction)seek:(id)sender 132 | { 133 | _player.currentTime = _player.duration * self.progressSlider.value; 134 | } 135 | @end 136 | -------------------------------------------------------------------------------- /PcmDataPlayer/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // PcmDataPlayer 4 | // 5 | // Created by Chengyin on 14-12-25. 6 | // Copyright (c) 2014年 Chengyin. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Player/AVAudioPlayer+PCM.h: -------------------------------------------------------------------------------- 1 | // 2 | // AVAudioPlayer+PCM.h 3 | // PcmDataPlayer 4 | // 5 | // Created by Chengyin on 14-12-25. 6 | // Copyright (c) 2014年 Chengyin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AVAudioPlayer (PCM) 12 | 13 | /** 14 | * AVAudioPlayer working with raw audio data 15 | * 16 | * @param pcmData raw audio data 17 | * @param format pcm format 18 | * @param outError return error 19 | * 20 | * @return AVAudioPlayer instance 21 | */ 22 | - (instancetype)initWithPcmData:(NSData *)pcmData pcmFormat:(AudioStreamBasicDescription)format error:(NSError **)outError; 23 | @end 24 | -------------------------------------------------------------------------------- /Player/AVAudioPlayer+PCM.m: -------------------------------------------------------------------------------- 1 | // 2 | // AVAudioPlayer+PCM.m 3 | // PcmDataPlayer 4 | // 5 | // Created by Chengyin on 14-12-25. 6 | // Copyright (c) 2014年 Chengyin. All rights reserved. 7 | // 8 | 9 | #import "AVAudioPlayer+PCM.h" 10 | 11 | @implementation AVAudioPlayer (PCM) 12 | 13 | - (instancetype)initWithPcmData:(NSData *)pcmData pcmFormat:(AudioStreamBasicDescription)pcmFormat error:(NSError **)outError 14 | { 15 | if (pcmFormat.mFormatID != kAudioFormatLinearPCM) 16 | { 17 | [[self class] _pcmPlayerErrorForErrorCode:AVErrorFileFormatNotRecognized reason:@"formatID is not equal to kAudioFormatLinearPCM" error:outError]; 18 | return nil; 19 | } 20 | 21 | NSData *wav = [[self class] _pcmPlayerFormatWavWithPcmData:pcmData pcmFormat:pcmFormat]; 22 | if (!wav) 23 | { 24 | [[self class] _pcmPlayerErrorForErrorCode:AVErrorFileFailedToParse reason:@"format wav data failded" error:outError]; 25 | return nil; 26 | } 27 | 28 | return [self initWithData:wav error:outError]; 29 | } 30 | 31 | /** 32 | * format wav data 33 | * 34 | * @param pcmData raw audio data 35 | * @param pcmFormat format of pcm 36 | * 37 | * @return wav data 38 | */ 39 | + (NSData *)_pcmPlayerFormatWavWithPcmData:(NSData *)pcmData pcmFormat:(AudioStreamBasicDescription)pcmFormat 40 | { 41 | // Following https://ccrma.stanford.edu/courses/422/projects/WaveFormat/ formating wav 42 | 43 | unsigned int pcmDataLength = (unsigned int)[pcmData length]; //pcm data length 44 | UInt32 wavHeaderSize = 44; //wav header size = 44 45 | 46 | SInt8 *wavHeader = (SInt8 *)malloc(wavHeaderSize); 47 | if (wavHeader == NULL) 48 | { 49 | return nil; 50 | } 51 | 52 | // ChunkID = 'RIFF' 53 | wavHeader[0x00] = 'R'; 54 | wavHeader[0x01] = 'I'; 55 | wavHeader[0x02] = 'F'; 56 | wavHeader[0x03] = 'F'; 57 | 58 | // Chunk = 36 + SubChunk2Size 59 | // or more precisely:4 + (8 + SubChunk1Size) + (8 + SubChunk2Size) 60 | *((SInt32 *)(wavHeader + 0x04)) = pcmDataLength + 36; 61 | 62 | // Format = 'WAVE' 63 | wavHeader[0x08] = 'W'; 64 | wavHeader[0x09] = 'A'; 65 | wavHeader[0x0A] = 'V'; 66 | wavHeader[0x0B] = 'E'; 67 | 68 | // Subchunk1ID = 'fmt ' 69 | wavHeader[0x0C] = 'f'; 70 | wavHeader[0x0D] = 'm'; 71 | wavHeader[0x0E] = 't'; 72 | wavHeader[0x0F] = ' '; 73 | 74 | // SubchunckSize = 16 for PCM 75 | wavHeader[0x10] = 16; 76 | wavHeader[0x11] = 0; 77 | wavHeader[0x12] = 0; 78 | wavHeader[0x13] = 0; 79 | 80 | // AudioFormat, PCM format = 1 81 | wavHeader[0x14] = 1; 82 | wavHeader[0x15] = 0; 83 | 84 | // NumChannels 85 | wavHeader[0x16] = pcmFormat.mChannelsPerFrame; 86 | wavHeader[0x17] = 0; 87 | 88 | // SampleRate 89 | const int sampleRate = pcmFormat.mSampleRate; 90 | const char *ptr = (const char*)&sampleRate; 91 | char sampleRate1 = *ptr++; 92 | char sampleRate2 = *ptr++; 93 | char sampleRate3 = *ptr++; 94 | char sampleRate4 = *ptr++; 95 | wavHeader[0x18] = sampleRate1; 96 | wavHeader[0x19] = sampleRate2; 97 | wavHeader[0x1A] = sampleRate3; 98 | wavHeader[0x1B] = sampleRate4; 99 | 100 | // ByteRate 101 | const int byteRate = pcmFormat.mSampleRate * pcmFormat.mBitsPerChannel * pcmFormat.mChannelsPerFrame / 8; 102 | ptr = (const char*)&byteRate; 103 | char byteRate1 = *ptr++; 104 | char byteRate2 = *ptr++; 105 | char byteRate3 = *ptr++; 106 | char byteRate4 = *ptr++; 107 | wavHeader[0x1C] = byteRate1; 108 | wavHeader[0x1D] = byteRate2; 109 | wavHeader[0x1E] = byteRate3; 110 | wavHeader[0x1F] = byteRate4; 111 | 112 | // BlockAlign (bytesPerSample) 113 | wavHeader[0x20] = pcmFormat.mBytesPerFrame; 114 | wavHeader[0x21] = 0; 115 | 116 | // BitsPerSample 117 | wavHeader[0x22] = pcmFormat.mBitsPerChannel; 118 | // ExtraParamSize if PCM, then doesn't exist 119 | wavHeader[0x23] = 0; 120 | 121 | // Subchunk2ID = 'data' 122 | wavHeader[0x24] = 'd'; 123 | wavHeader[0x25] = 'a'; 124 | wavHeader[0x26] = 't'; 125 | wavHeader[0x27] = 'a'; 126 | 127 | // SubChunkSize = NumSamples * NumChannels * BitsPerSample/8. This is the number of bytes in the data. 128 | *((SInt32 *)(wavHeader + 0x28)) = pcmDataLength; 129 | 130 | NSMutableData *wavData = [NSMutableData dataWithBytes:wavHeader length:wavHeaderSize]; 131 | free(wavHeader); 132 | 133 | // Append pcm data 134 | [wavData appendData:pcmData]; 135 | return wavData; 136 | } 137 | 138 | /** 139 | * format error 140 | * 141 | * @param code error code 142 | * @param reason error reason 143 | * @param outError return error 144 | */ 145 | + (void)_pcmPlayerErrorForErrorCode:(AVError)code reason:(NSString *)reason error:(NSError *__autoreleasing *)outError 146 | { 147 | if (outError != NULL) 148 | { 149 | NSMutableDictionary *userInfo = [@{NSLocalizedDescriptionKey:@"The operation couldn’t be completed."} mutableCopy]; 150 | if (reason) 151 | { 152 | userInfo[NSLocalizedFailureReasonErrorKey] = reason; 153 | } 154 | *outError = [NSError errorWithDomain:AVFoundationErrorDomain code:code userInfo:userInfo]; 155 | } 156 | } 157 | @end 158 | -------------------------------------------------------------------------------- /Player/AVAudioPlayer+Sample.h: -------------------------------------------------------------------------------- 1 | // 2 | // AVAudioPlayer+Sample.h 3 | // PcmDataPlayer 4 | // 5 | // Created by Chengyin on 15/12/21. 6 | // Copyright © 2015年 Chengyin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AVAudioPlayer (Sample) 12 | + (instancetype)sp_createPlayer:(NSString *)path; 13 | @end 14 | -------------------------------------------------------------------------------- /Player/AVAudioPlayer+Sample.m: -------------------------------------------------------------------------------- 1 | // 2 | // AVAudioPlayer+Sample.m 3 | // PcmDataPlayer 4 | // 5 | // Created by Chengyin on 15/12/21. 6 | // Copyright © 2015年 Chengyin. All rights reserved. 7 | // 8 | 9 | #import "AVAudioPlayer+Sample.h" 10 | #import "AVAudioPlayer+PCM.h" 11 | 12 | @implementation AVAudioPlayer (Sample) 13 | + (AudioStreamBasicDescription)sp_format 14 | { 15 | AudioStreamBasicDescription format; 16 | format.mFormatID = kAudioFormatLinearPCM; 17 | format.mSampleRate = 44100; 18 | 19 | format.mBitsPerChannel = 16; 20 | format.mChannelsPerFrame = 2; 21 | format.mBytesPerFrame = format.mChannelsPerFrame * (format.mBitsPerChannel / 8); 22 | 23 | format.mFramesPerPacket = 1; 24 | format.mBytesPerPacket = format.mFramesPerPacket * format.mBytesPerFrame; 25 | 26 | format.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked; 27 | 28 | return format; 29 | } 30 | 31 | + (instancetype)sp_createPlayer:(NSString *)path 32 | { 33 | NSData *pcmData = [NSData dataWithContentsOfFile:path]; 34 | NSError *error = nil; 35 | AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithPcmData:pcmData pcmFormat:[self sp_format] error:&error]; 36 | player.numberOfLoops = -1; 37 | return player; 38 | } 39 | @end 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PcmDataPlayer 2 | ============= 3 | 4 | Playing raw audio data with AVAudioPlayer 5 | 6 | Based on [@hollance](https://github.com/hollance)'s code [AVBufferPlayer](https://github.com/hollance/AVBufferPlayer) 7 | -------------------------------------------------------------------------------- /Sample/pcmData: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msching/PcmDataPlayer/145402fdf4d32cc78b21fa288075587a5096c329/Sample/pcmData -------------------------------------------------------------------------------- /Util/NSTimer+BlocksSupport.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSTimer+BlocksSupport.h 3 | // MCSimpleAudioPlayerDemo 4 | // 5 | // Created by Chengyin on 15-3-13. 6 | // Copyright (c) 2015年 Netease. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSTimer (BlocksSupport) 12 | + (NSTimer*)bs_scheduledTimerWithTimeInterval:(NSTimeInterval)interval block:(void(^)())block repeats:(BOOL)repeats; 13 | @end 14 | -------------------------------------------------------------------------------- /Util/NSTimer+BlocksSupport.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSTimer+BlocksSupport.m 3 | // MCSimpleAudioPlayerDemo 4 | // 5 | // Created by Chengyin on 15-3-13. 6 | // Copyright (c) 2015年 Netease. All rights reserved. 7 | // 8 | 9 | #import "NSTimer+BlocksSupport.h" 10 | 11 | @implementation NSTimer (BlocksSupport) 12 | + (NSTimer*)bs_scheduledTimerWithTimeInterval:(NSTimeInterval)interval block:(void(^)())block repeats:(BOOL)repeats 13 | { 14 | return [self scheduledTimerWithTimeInterval:interval target:self selector:@selector(bs_blockInvoke:) userInfo:[block copy] repeats:repeats]; 15 | } 16 | 17 | + (void)bs_blockInvoke:(NSTimer*)timer 18 | { 19 | void (^block)() = timer.userInfo; 20 | if (block) 21 | { 22 | block(); 23 | } 24 | } 25 | @end 26 | --------------------------------------------------------------------------------