Hallo,
ich habe ein kleines Problem, ich weiss nicht wie ich sounds wieder aus dem Speicher bekomme, wenn ich diese nur einmal im Programm brauche und danach gerne z.b. einen neuen Soundtrack laden möchte.
Meine Soundfunktion habe ich mal nach Lehrbuch aufgebaut. Jetzt hätte ich gerne Funktion alla: (void) unLoadSound: (NSString*) soundName; checke aber nicht wie die aussehen muss.
Alles anzeigen
und die .m:
Alles anzeigen
Hat jemand ein Codehäppchen das passt?
VG
Rayjunx
ich habe ein kleines Problem, ich weiss nicht wie ich sounds wieder aus dem Speicher bekomme, wenn ich diese nur einmal im Programm brauche und danach gerne z.b. einen neuen Soundtrack laden möchte.
Meine Soundfunktion habe ich mal nach Lehrbuch aufgebaut. Jetzt hätte ich gerne Funktion alla: (void) unLoadSound: (NSString*) soundName; checke aber nicht wie die aussehen muss.
Quellcode
- #import <Foundation/Foundation.h>
- #import <OpenAL/al.h>
- #import <OpenAL/alc.h>
- #import <AudioToolbox/AudioToolbox.h>
- @interface SoundOAL : NSObject {
- ALCcontext *context;
- ALCdevice *device;
- NSMutableArray *soundIDs;
- NSMutableDictionary *soundIDDictionary; //dynamisch
- NSMutableDictionary *soundBufferIDDictionary;
- }
- + (SoundOAL *) getInstance;
- - (void) setupOpenAL;
- - (void) logErrors: (OSStatus) status;
- - (NSUInteger) findFreeSoundID;
- - (void) loadSound: (NSString*) soundName
- Hz: (NSUInteger) sampleRate;
- - (void) playSound: (NSString*) soundName
- pitch: (float) pitch
- volume: (float) volume;
- - (void) loopSound: (NSString*) soundName
- pitch: (float) pitch
- volume: (float) volume;
- - (void) stopSound: (NSString*) soundName;
- @end
und die .m:
Quellcode
- #import "SoundOAL.h"
- @implementation SoundOAL
- + (SoundOAL *) getInstance {
- static SoundOAL *sound;
- @synchronized (self) {
- if(!sound) {
- sound = [[SoundOAL alloc] init];
- [sound setupOpenAL];
- }
- }
- return sound;
- }
- - (void) setupOpenAL {
- soundIDs = [[NSMutableArray alloc] init];
- soundIDDictionary = [[NSMutableDictionary alloc] init];
- soundBufferIDDictionary = [[NSMutableDictionary alloc] init];
- device = alcOpenDevice(NULL);
- if (device) {
- context = alcCreateContext(device, NULL);
- alcMakeContextCurrent(context);
- int maxSounds = 22; //Polyphonie: wir haben mehr Slots als Sounds
- for (int i = 0; i < maxSounds; i++) {
- NSUInteger soundID;
- alGenSources(1, &soundID); //Sound-IDs erzeugen
- [soundIDs addObject: [NSNumber numberWithUnsignedInt: soundID]];
- }
- [self logErrors: 0];
- }
- }
- //Sounddaten mit Hilfe der Audio File API einlesen (AudioToolbox)
- - (void) loadSound:(NSString*) soundName
- Hz:(NSUInteger) sampleRate {
- //Sound-Datei oeffnen und fileID zuweisen
- OSStatus status;
- AudioFileID fileID;
- NSString *path = [[NSBundle mainBundle] pathForResource: soundName ofType: nil];
- NSURL *afUrl = [NSURL fileURLWithPath: path];
- status = AudioFileOpenURL((CFURLRef) afUrl, kAudioFileReadPermission, 0, &fileID);
- [self logErrors: status];
- //Dateigroesse (fileSize) ermitteln
- UInt64 outDataSize = 0; //file size in bytes
- UInt32 thePropSize = sizeof(UInt64);
- status = AudioFileGetProperty(fileID, kAudioFilePropertyAudioDataByteCount, &thePropSize, &outDataSize);
- [self logErrors: status];
- UInt32 fileSize = (UInt32) outDataSize;
- //Sounddaten temporaer einlesen
- unsigned char *tempData = malloc(fileSize); //hier landen die einzelnen Samples
- status = AudioFileReadBytes(fileID, FALSE, 0, &fileSize, tempData);
- [self logErrors: status];
- status = AudioFileClose(fileID);
- //Einen neuen Audio-Buffer erzeugen
- NSUInteger bufferID;
- alGenBuffers(1, &bufferID);
- //Sounddaten als Raw Bytes in den Buffer schreiben (ohne Header-Information)
- alBufferData(bufferID, AL_FORMAT_STEREO16, tempData, fileSize, sampleRate);
- //Buffer in einem Dictionary ablegen
- [soundBufferIDDictionary setObject: [NSNumber numberWithUnsignedInt: bufferID] forKey: soundName];
- if(tempData) {
- free(tempData);
- tempData = NULL;
- }
- [self logErrors: status];
- }
- - (void) playSound: (NSString*) soundName
- pitch: (float) pitch
- volume: (float) volume
- {
- NSUInteger bufferID = [[soundBufferIDDictionary objectForKey: soundName] unsignedIntValue];
- NSUInteger soundID = [self findFreeSoundID];
- [soundIDDictionary setObject: [NSNumber numberWithUnsignedInt: soundID] forKey: soundName];
- alSourcei(soundID, AL_BUFFER, 0); //Alte Buffer-Daten loeschen
- alSourcei(soundID, AL_BUFFER, bufferID); //Neue Buffer-Daten an die ID binden
- //Sound-Eigenschaften
- alSourcef(soundID, AL_PITCH, pitch); // abspielgeschwindigkeits faktor
- alSourcef(soundID, AL_GAIN, volume); // Volume
- alSourcei(soundID, AL_LOOPING, AL_FALSE);
- alSourcePlay(soundID);
- [self logErrors: 0];
- }
- - (void) loopSound: (NSString*) soundName
- pitch: (float) pitch
- volume: (float) volume
- {
- NSUInteger bufferID = [[soundBufferIDDictionary objectForKey: soundName] unsignedIntValue];
- NSUInteger soundID = [self findFreeSoundID];
- [soundIDDictionary setObject: [NSNumber numberWithUnsignedInt: soundID] forKey: soundName];
- alSourcei(soundID, AL_BUFFER, 0); //Alte Buffer-Daten loeschen
- alSourcei(soundID, AL_BUFFER, bufferID); //Neue Buffer-Daten an die ID binden
- //Sound-Eigenschaften
- alSourcef(soundID, AL_PITCH, pitch);
- alSourcef(soundID, AL_GAIN, volume);
- alSourcei(soundID, AL_LOOPING, AL_TRUE);
- alSourcePlay(soundID);
- [self logErrors: 0];
- }
- - (void) stopSound: (NSString*) soundName {
- id obj = [soundIDDictionary objectForKey: soundName];
- if (obj != NULL) {
- NSUInteger soundID = [obj unsignedIntValue];
- alSourceStop(soundID);
- [self logErrors: 0];
- }
- }
- - (NSUInteger) findFreeSoundID {
- for (NSNumber *aSoundID in soundIDs) {
- NSInteger idState;
- alGetSourcei([aSoundID unsignedIntValue], AL_SOURCE_STATE, &idState);
- if(idState != AL_PLAYING) return [aSoundID unsignedIntValue];
- }
- //Wenn alle Sounds abgepspielt werden, wird der aelteste Sound ersetzt
- NSUInteger soundID = [[soundIDs objectAtIndex:0] unsignedIntegerValue];
- alSourceStop(soundID);
- [self logErrors: 0];
- return soundID;
- }
- - (void) logErrors: (OSStatus) status {
- ALenum err = alGetError();
- if (err != 0) {
- NSLog(@"ERROR OpenAL: %d", err);
- }
- if (status != 0) {
- NSLog(@"ERROR OSStatus: %ld", (long) status);
- }
- }
- - (void) dealloc {
- //Sound-IDs loeschen
- for(NSNumber *soundID in soundIDs) {
- NSUInteger sID = [soundID unsignedIntValue];
- alDeleteSources(1, &sID);
- }
- //Buffer-Daten loeschen
- NSEnumerator *enumerator = [soundBufferIDDictionary keyEnumerator];
- id key;
- while ((key = [enumerator nextObject])) {
- NSNumber *bufferID = [soundBufferIDDictionary objectForKey: key];
- NSUInteger bID = [bufferID unsignedIntValue];
- alDeleteBuffers(1, &bID);
- }
- [soundIDDictionary release];
- [soundBufferIDDictionary release];
- [soundIDs release];
- alcMakeContextCurrent(NULL);
- alcDestroyContext(context);
- alcCloseDevice(device);
- [self logErrors: 0];
- [super dealloc];
- }
- @end
Hat jemand ein Codehäppchen das passt?
VG
Rayjunx
Just a bloggingFreak raysspieleschmiede.blogspot.de freakwave-games.blogspot.de