Giter Site home page Giter Site logo

Add MP3 decoding about finch HOT 5 OPEN

zoul avatar zoul commented on August 22, 2024
Add MP3 decoding

from finch.

Comments (5)

zoul avatar zoul commented on August 22, 2024

I’d like to do this, but it’s very low priority, since I don’t need it myself. Not expected to come in the upcoming months.

from finch.

nornagon avatar nornagon commented on August 22, 2024

I needed it, so I have a patch that does it. I'll clean it up and send
a pull request.

On Fri, May 6, 2011 at 12:15 AM, zoul
[email protected]
wrote:

I’d like to do this, but it’s very low priority, since I don’t need it myself. Not expected to come in the upcoming months.

Reply to this email directly or view it on GitHub:
#14 (comment)

from finch.

pomarec avatar pomarec commented on August 22, 2024

nornagon, I would love to use it !

from finch.

nornagon avatar nornagon commented on August 22, 2024

Don't have the time to clean it up and make a proper pull request right now (or even to test that the code still works) but here's the patch I made. IIRC I copied the code to load mp3s from cocos2d.

diff --git a/Source/PCMDecoder.m b/Source/PCMDecoder.m
index bd885f3..3787b54 100644
--- a/Source/PCMDecoder.m
+++ b/Source/PCMDecoder.m
@@ -1,90 +1,123 @@
 #import "PCMDecoder.h"
-#import  
+#import 
+#import 
 #import "Sample.h"
 #import "Reporter.h"
+#import 
 
 @implementation PCMDecoder
 
 + (Sample*) decodeFile: (NSURL*) fileURL error: (NSError**) error
 {
-    OSStatus errcode = noErr;
-    UInt32 propertySize;
-    AudioFileID fileId = 0;
-    Reporter *reporter = [Reporter forDomain:@"Sample Decoder" error:error];
-    
-    errcode = AudioFileOpenURL((CFURLRef) fileURL, kAudioFileReadPermission, 0, &fileId);
-    if (errcode) {
-        *error = [reporter errorWithCode:kDEFileReadError];
-        return nil;
-    }
-    
-    AudioStreamBasicDescription fileFormat;
-    propertySize = sizeof(fileFormat);
-    errcode = AudioFileGetProperty(fileId, kAudioFilePropertyDataFormat, &propertySize, &fileFormat);
-    if (errcode) {
-        *error = [reporter errorWithCode:kDEFileFormatReadError];
-        AudioFileClose(fileId);
-        return nil;
-    }
-
-    if (fileFormat.mFormatID != kAudioFormatLinearPCM) { 
-        *error = [reporter
-            errorWithCode:kDEInvalidFileFormat
-            description:@"Sound file not linear PCM."];
-        AudioFileClose(fileId);
-        return nil;
-    }
-    
-    UInt64 fileSize = 0;
-    propertySize = sizeof(fileSize);
-    errcode = AudioFileGetProperty(fileId, kAudioFilePropertyAudioDataByteCount, &propertySize, &fileSize);
-    if (errcode) {
-        *error = [reporter
-            errorWithCode:kDEFileFormatReadError
-            description:@"Failed to read sound file size."];
-        AudioFileClose(fileId);
-        return nil;
-    }
-
-    double sampleLength = -1;
-    propertySize = sizeof(sampleLength);
-    errcode = AudioFileGetProperty(fileId, kAudioFilePropertyEstimatedDuration, &propertySize, &sampleLength);
-    if (errcode) {
-        *error = [reporter
-            errorWithCode:kDEFileFormatReadError
-            description:@"Failed to read sound length."];
-        AudioFileClose(fileId);
-        return nil;
-    }
-
-    UInt32 dataSize = (UInt32) fileSize;
-    void *data = malloc(dataSize);
-    if (!data) {
-        *error = [reporter errorWithCode:kDEMemoryAllocationError];
-        AudioFileClose(fileId);
-        return nil;
-    }
-    
-    errcode = AudioFileReadBytes(fileId, false, 0, &dataSize, data);
-    if (errcode) {
-        *error = [reporter
-            errorWithCode:kDEFileFormatReadError
-            description:@"Failed to read sound data."];
-        free(data);
-        AudioFileClose(fileId);
-        return nil;
-    }
-
-    Sample *sample = [[Sample alloc] init];
-    [sample setChannels:fileFormat.mChannelsPerFrame];
-    [sample setEndianity:TestAudioFormatNativeEndian(fileFormat) ? kLittleEndian : kBigEndian];
-    [sample setBitsPerChannel:fileFormat.mBitsPerChannel];
-    [sample setSampleRate:fileFormat.mSampleRate];
-    [sample setDuration:sampleLength];
-    [sample setData:[NSData dataWithBytesNoCopy:data length:dataSize freeWhenDone:YES]];
-    
-    AudioFileClose(fileId);
-    return [sample autorelease];
+   OSStatus errcode = noErr;
+   UInt32 propertySize;
+   ExtAudioFileRef fileRef = 0;
+   Reporter *reporter = [Reporter forDomain:@"Sample Decoder" error:error];
+   
+   errcode = ExtAudioFileOpenURL((CFURLRef) fileURL, &fileRef);
+   if (errcode) {
+       *error = [reporter errorWithCode:kDEFileReadError];
+       return nil;
+   }
+   
+   AudioStreamBasicDescription fileFormat;
+   propertySize = sizeof(fileFormat);
+   errcode = ExtAudioFileGetProperty(fileRef, kExtAudioFileProperty_FileDataFormat, &propertySize, &fileFormat);
+   if (errcode) {
+       *error = [reporter errorWithCode:kDEFileFormatReadError];
+       ExtAudioFileDispose(fileRef);
+       return nil;
+   }
+   
+   if (fileFormat.mChannelsPerFrame > 2) {
+       *error = [reporter
+                           errorWithCode:kDEFileFormatReadError
+                           description:@"Too many channels (better than stereo!)."];
+       ExtAudioFileDispose(fileRef);
+       return nil;
+   }
+   
+   AudioStreamBasicDescription theOutputFormat;
+   
+   theOutputFormat.mSampleRate = fileFormat.mSampleRate;
+   theOutputFormat.mChannelsPerFrame = fileFormat.mChannelsPerFrame;
+   
+   theOutputFormat.mFormatID = kAudioFormatLinearPCM;
+   theOutputFormat.mBytesPerPacket = 2 * theOutputFormat.mChannelsPerFrame;
+   theOutputFormat.mFramesPerPacket = 1;
+   theOutputFormat.mBytesPerFrame = 2 * theOutputFormat.mChannelsPerFrame;
+   theOutputFormat.mBitsPerChannel = 16;
+   theOutputFormat.mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger;
+   
+   errcode = ExtAudioFileSetProperty(fileRef, kExtAudioFileProperty_ClientDataFormat, sizeof(theOutputFormat), &theOutputFormat);
+   if (errcode) {
+       *error = [reporter
+                           errorWithCode:kDEFileFormatReadError
+                           description:@"Couldn't set output format..."];
+       ExtAudioFileDispose(fileRef);
+       return nil;     
+   }
+   
+   
+   // Get the total frame count
+   SInt64 numFrames;
+   propertySize = sizeof(numFrames);
+   errcode = ExtAudioFileGetProperty(fileRef, kExtAudioFileProperty_FileLengthFrames, &propertySize, &numFrames);
+   if (errcode) {
+       *error = [reporter
+                           errorWithCode:kDEFileFormatReadError
+                           description:@"Couldn't set output format..."];
+       ExtAudioFileDispose(fileRef);
+       return nil;
+   }
+   
+   // Read all the data into memory
+   UInt64 dataSize = numFrames * theOutputFormat.mBytesPerFrame;
+   void *data = malloc(dataSize);
+   
+   ALsizei outDataSize;
+   ALenum outFormat;
+   ALsizei outSampleRate;
+   
+   if (data) {
+       AudioBufferList     theDataBuffer;
+       theDataBuffer.mNumberBuffers = 1;
+       theDataBuffer.mBuffers[0].mDataByteSize = dataSize;
+       theDataBuffer.mBuffers[0].mNumberChannels = theOutputFormat.mChannelsPerFrame;
+       theDataBuffer.mBuffers[0].mData = data;
+       
+       // Read the data into an AudioBufferList
+       errcode = ExtAudioFileRead(fileRef, (UInt32*)&numFrames, &theDataBuffer);
+       if(errcode == noErr)
+       {
+           // success
+           outDataSize = (ALsizei)dataSize;
+           outFormat = (theOutputFormat.mChannelsPerFrame > 1) ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16;
+           outSampleRate = (ALsizei)theOutputFormat.mSampleRate;
+       }
+       else
+       {
+           // failure
+           free (data);
+           data = nil;
+           *error = [reporter
+                               errorWithCode:kDEFileFormatReadError
+                               description:@"Couldn't set output format..."];
+           ExtAudioFileDispose(fileRef);
+           return nil;
+       }
+   }
+   
+   Sample *sample = [[Sample alloc] init];
+   [sample setChannels:theOutputFormat.mChannelsPerFrame];
+   [sample setEndianity:TestAudioFormatNativeEndian(theOutputFormat) ? kLittleEndian : kBigEndian];
+   [sample setBitsPerChannel:theOutputFormat.mBitsPerChannel];
+   [sample setSampleRate:theOutputFormat.mSampleRate];
+   //[sample setDuration:sampleLength];
+   [sample setData:[NSData dataWithBytesNoCopy:data length:dataSize freeWhenDone:YES]];
+   
+   ExtAudioFileDispose(fileRef);
+   return [sample autorelease];
 }
 
 + (void) load
diff --git a/Source/Sound.h b/Source/Sound.h
index 124ee6a..aa4b8ed 100644
--- a/Source/Sound.h
+++ b/Source/Sound.h
@@ -41,5 +41,6 @@ enum SoundError {
 
 - (void) play;
 - (void) stop;
+- (void) pause;
 
 @end
diff --git a/Source/Sound.m b/Source/Sound.m
index b552834..4bc5ff7 100644
--- a/Source/Sound.m
+++ b/Source/Sound.m
@@ -159,4 +159,13 @@
     [self checkSuccessOrLog:@"Failed to stop sound"];
 }
 
+- (void) pause
+{
+   if (!self.playing)
+       return;
+   CLEAR_ERROR_FLAG;
+   alSourcePause(source);
+   [self checkSuccessOrLog:@"Failed to pause sound"];
+}
+
 @end

from finch.

BobDG avatar BobDG commented on August 22, 2024

Does anybody have a working example with the code from nornagon? I can't seem to get it to work!

from finch.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.