/FakeWebGL/WebGL/FakeAudio.ios.mm

https://github.com/bagobor/FakeWebGL · Objective C++ · 112 lines · 83 code · 11 blank · 18 comment · 15 complexity · bea619e39c5f45926887da48ed43ba1c MD5 · raw file

  1. //
  2. // FakeAudio.ios.m
  3. // webglshim
  4. //
  5. // Created by Rolando Abarca on 11/2/12.
  6. // Copyright (c) 2012 Rolando Abarca. All rights reserved.
  7. //
  8. #import "FakeAudio.h"
  9. #import <AudioToolbox/AudioToolbox.h>
  10. #import <AudioToolbox/ExtendedAudioFile.h>
  11. void* OpenALBuffer::getData()
  12. {
  13. void * data = NULL;
  14. NSString* fullPath = [NSString stringWithUTF8String:getFullPathFromRelativePath(src.c_str())];
  15. NSURL* url = [NSURL fileURLWithPath:fullPath];
  16. // Open the file
  17. ExtAudioFileRef file = NULL;
  18. OSStatus error = ExtAudioFileOpenURL((__bridge CFURLRef)url, &file);
  19. if (error) {
  20. NSLog(@"OpenALSource: ExtAudioFileOpenURL FAILED, Error = %ld", error);
  21. if (file)
  22. ExtAudioFileDispose(file);
  23. return data;
  24. }
  25. // Get the audio data format
  26. AudioStreamBasicDescription inputFormat;
  27. UInt32 propertySize = sizeof(inputFormat);
  28. error = ExtAudioFileGetProperty(file, kExtAudioFileProperty_FileDataFormat, &propertySize, &inputFormat);
  29. if (error) {
  30. NSLog(@"OpenALSource: ExtAudioFileGetProperty(kExtAudioFileProperty_FileDataFormat) FAILED, Error = %ld", error);
  31. if (file)
  32. ExtAudioFileDispose(file);
  33. return data;
  34. }
  35. if (inputFormat.mChannelsPerFrame > 2) {
  36. NSLog(@"OpenALSource: Unsupported Format, channel count is greater than stereo");
  37. if (file)
  38. ExtAudioFileDispose(file);
  39. return data;
  40. }
  41. // Set the client format to 16 bit signed integer (native-endian) data
  42. // Maintain the channel count and sample rate of the original source format
  43. AudioStreamBasicDescription outputFormat = {
  44. .mSampleRate = inputFormat.mSampleRate,
  45. .mChannelsPerFrame = inputFormat.mChannelsPerFrame,
  46. .mFormatID = kAudioFormatLinearPCM,
  47. .mBytesPerPacket = 2 * inputFormat.mChannelsPerFrame,
  48. .mFramesPerPacket = 1,
  49. .mBytesPerFrame = 2 * inputFormat.mChannelsPerFrame,
  50. .mBitsPerChannel = 16,
  51. .mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger
  52. };
  53. // Set the desired client (output) data format
  54. error = ExtAudioFileSetProperty(file, kExtAudioFileProperty_ClientDataFormat, sizeof(outputFormat), &outputFormat);
  55. if (error) {
  56. NSLog(@"OpenALSource: ExtAudioFileSetProperty(kExtAudioFileProperty_ClientDataFormat) FAILED, Error = %ld", error);
  57. if (file)
  58. ExtAudioFileDispose(file);
  59. return data;
  60. }
  61. // Get the total frame count
  62. SInt64 frameCount = 0;
  63. propertySize = sizeof(frameCount);
  64. error = ExtAudioFileGetProperty(file, kExtAudioFileProperty_FileLengthFrames, &propertySize, &frameCount);
  65. if (error) {
  66. NSLog(@"OpenALSource: ExtAudioFileGetProperty(kExtAudioFileProperty_FileLengthFrames) FAILED, Error = %ld", error);
  67. if (file)
  68. ExtAudioFileDispose(file);
  69. return data;
  70. }
  71. // Read all the data into memory
  72. int dataSize = frameCount * outputFormat.mBytesPerFrame;
  73. data = malloc(dataSize);
  74. AudioBufferList bufferList;
  75. bufferList.mNumberBuffers = 1;
  76. bufferList.mBuffers[0].mDataByteSize = dataSize;
  77. bufferList.mBuffers[0].mNumberChannels = outputFormat.mChannelsPerFrame;
  78. bufferList.mBuffers[0].mData = data;
  79. // Read the data into an AudioBufferList
  80. error = ExtAudioFileRead(file, (UInt32*)&frameCount, &bufferList);
  81. if (error == noErr) {
  82. // success
  83. size = (ALsizei)dataSize;
  84. format = (outputFormat.mChannelsPerFrame > 1) ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16;
  85. sampleRate = (ALsizei)outputFormat.mSampleRate;
  86. }
  87. else {
  88. // failure
  89. free(data);
  90. data = NULL;
  91. NSLog(@"OpenALSource: ExtAudioFileRead FAILED, Error = %ld", error);
  92. if (file)
  93. ExtAudioFileDispose(file);
  94. return data;
  95. }
  96. // Dispose the ExtAudioFileRef, it is no longer needed
  97. if (file) {
  98. ExtAudioFileDispose(file);
  99. }
  100. return data;
  101. }