LCOV - code coverage report
Current view: top level - Core - OOALSoundChannel.m (source / functions) Hit Total Coverage
Test: coverxygen.info Lines: 0 9 0.0 %
Date: 2025-05-28 07:50:54 Functions: 0 0 -

          Line data    Source code
       1           0 : /*
       2             : 
       3             : OOALSoundChannel.m
       4             : 
       5             : OOALSound - OpenAL sound implementation for Oolite.
       6             : Copyright (C) 2006-2013 Jens Ayton
       7             : 
       8             : Permission is hereby granted, free of charge, to any person obtaining a copy
       9             : of this software and associated documentation files (the "Software"), to deal
      10             : in the Software without restriction, including without limitation the rights
      11             : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      12             : copies of the Software, and to permit persons to whom the Software is
      13             : furnished to do so, subject to the following conditions:
      14             : 
      15             : The above copyright notice and this permission notice shall be included in all
      16             : copies or substantial portions of the Software.
      17             : 
      18             : THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      19             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      20             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      21             : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      22             : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      23             : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      24             : SOFTWARE.
      25             : 
      26             : */
      27             : 
      28             : #import "OOALSoundChannel.h"
      29             : #import "OOALSound.h"
      30             : #import "OOLogging.h"
      31             : #import "OOMaths.h"
      32             : 
      33             : @interface OOSoundChannel (Private)
      34             : 
      35           0 : - (BOOL) enqueueBuffer:(OOSound *)sound;
      36           0 : - (void) hasStopped;
      37           0 : - (void) getNextSoundBuffer;
      38             : 
      39             : @end
      40             : 
      41             : 
      42             : @implementation OOSoundChannel
      43             : 
      44           0 : - (id) init
      45             : {
      46             :         if ((self = [super init]))
      47             :         {
      48             :                 ALuint error;
      49             :                 OOAL(alGenSources(1,&_source));
      50             :                 if ((error = alGetError()) != AL_NO_ERROR)
      51             :                 {
      52             :                         OOLog(kOOLogSoundInitError, @"%@", @"Could not create OpenAL source");
      53             :                         [self release];
      54             :                         self = nil;
      55             :                 }
      56             :                 else
      57             :                 {
      58             :                         // sources are all relative to listener, defaulting to zero vector
      59             :                         OOAL(alSourcei(_source, AL_SOURCE_RELATIVE, AL_TRUE));
      60             :                         OOAL(alSource3f(_source, AL_POSITION, 0.0f, 0.0f, 0.0f));
      61             :                 }
      62             :         }
      63             :         return self;
      64             : }
      65             : 
      66             : 
      67           0 : - (void) dealloc
      68             : {
      69             :         [self hasStopped]; // make sure buffers are dequeued and deleted
      70             :         OOAL(alDeleteSources(1, &_source));
      71             :         [super dealloc];
      72             : }
      73             : 
      74             : - (void) update
      75             : {
      76             :         // Check if we've reached the end of a sound.
      77             :         if (_sound != nil)
      78             :         {
      79             :                 ALint check;
      80             :                 OOAL(alGetSourcei(_source,AL_SOURCE_STATE,&check));
      81             :                 if (check == AL_STOPPED)
      82             :                 {
      83             :                         [self hasStopped];
      84             :                 }
      85             :                 else if ([_sound soundIncomplete]) // streaming and not finished loading
      86             :                 {
      87             :                         OOLog(@"sound.buffer", @"Incomplete, trying next for %@", [_sound name]);
      88             :                         [self getNextSoundBuffer];
      89             :                 }
      90             :                 else if (_loop)
      91             :                 {
      92             :                         OOLog(@"sound.buffer", @"Looping, trying restart for %@", [_sound name]);
      93             :                         // sound is complete, but needs to be looped, so start it again
      94             :                         [_sound rewind];
      95             :                         [self getNextSoundBuffer];
      96             :                 }
      97             :         }
      98             : }
      99             : 
     100             : 
     101           0 : - (void) getNextSoundBuffer
     102             : {
     103             :         if (!_bigSound)
     104             :         {
     105             :                 // we've only loaded one buffer so far
     106             :                 _bigSound = YES;
     107             :                 _lastBuffer = _buffer;
     108             :                 [self enqueueBuffer:_sound];
     109             :         }
     110             :         else
     111             :         {
     112             :                 // _lastBuffer has something in it, so only queue up
     113             :                 // another one if we've finished with that
     114             :                 ALint processed = 0;
     115             :                 OOAL(alGetSourcei(_source, AL_BUFFERS_PROCESSED, &processed));
     116             :                 if (processed > 0) // slot free
     117             :                 {
     118             :                         // dequeue and delete lastBuffer
     119             :                         ALuint buffer;
     120             :                         OOAL(alSourceUnqueueBuffers(_source, 1, &buffer));
     121             :                         assert(buffer == _lastBuffer);
     122             :                         OOAL(alDeleteBuffers(1,&_lastBuffer));
     123             :                         // shuffle along, and grab the next bit
     124             :                         _lastBuffer = _buffer;
     125             :                         [self enqueueBuffer:_sound];
     126             :                 }
     127             :         }
     128             : }
     129             : 
     130             : 
     131             : - (void) setDelegate:(id)delegate
     132             : {
     133             :         _delegate = delegate;
     134             : }
     135             : 
     136             : 
     137             : - (OOSoundChannel *) next
     138             : {
     139             :         return _next;
     140             : }
     141             : 
     142             : 
     143             : - (void) setNext:(OOSoundChannel *)next
     144             : {
     145             :         _next = next;
     146             : }
     147             : 
     148             : 
     149             : - (void) setPosition:(Vector) vector
     150             : {
     151             :         OOAL(alSource3f(_source, AL_POSITION, vector.x, vector.y, vector.z));
     152             : }
     153             : 
     154             : 
     155             : - (void) setGain:(float) gain
     156             : {
     157             :         OOAL(alSourcef(_source, AL_GAIN, gain));
     158             : }
     159             : 
     160             : 
     161             : - (BOOL) playSound:(OOSound *)sound looped:(BOOL)loop
     162             : {
     163             :         if (sound == nil)  return NO;
     164             :         
     165             :         if (_sound != nil)  [self stop];
     166             : 
     167             :         _loop = loop;
     168             :         _bigSound = NO;
     169             :         [sound rewind];
     170             :         if ([self enqueueBuffer:sound])
     171             :         {
     172             :                 _sound = [sound retain];
     173             :                 return YES;
     174             :         }
     175             :         else
     176             :         {
     177             :                 return NO;
     178             :         }
     179             : }
     180             : 
     181             : 
     182             : - (void) stop
     183             : {
     184             :         if (_sound != nil)
     185             :         {
     186             :                 OOAL(alSourceStop(_source));
     187             :                 OOAL(alSourcei(_source, AL_BUFFER, AL_NONE));
     188             :                 [self hasStopped];
     189             :         }
     190             : }
     191             : 
     192             : 
     193           0 : - (void) hasStopped
     194             : {
     195             :         ALint queued;
     196             :         OOAL(alGetSourcei(_source, AL_BUFFERS_QUEUED, &queued));
     197             :     
     198             :         while (queued--)
     199             :         {
     200             :                 ALuint buffer;
     201             :                 OOAL(alSourceUnqueueBuffers(_source, 1, &buffer));
     202             :         }
     203             : 
     204             :         OOAL(alDeleteBuffers(1,&_buffer));
     205             :         if (_bigSound)
     206             :         {
     207             :                 // then we have two buffers to cleanup
     208             :                 OOAL(alDeleteBuffers(1,&_lastBuffer));
     209             :         }
     210             :         _bigSound = NO;
     211             : 
     212             : 
     213             :         OOSound *sound = _sound;
     214             :         _sound = nil;
     215             :         
     216             :         if (nil != _delegate && [_delegate respondsToSelector:@selector(channel:didFinishPlayingSound:)])
     217             :         {
     218             :                 [_delegate channel:self didFinishPlayingSound:sound];
     219             :         }
     220             :         [sound release];
     221             : }
     222             : 
     223             : 
     224           0 : - (BOOL) enqueueBuffer:(OOSound *)sound
     225             : {
     226             :         // get sound data
     227             :         _buffer = [sound soundBuffer];
     228             :         // bind sound data to buffer
     229             :         OOAL(alSourceQueueBuffers(_source, 1, &_buffer));
     230             :         ALuint error;
     231             :         if ((error = alGetError()) != AL_NO_ERROR)
     232             :         {
     233             :                 OOLog(@"ov.debug", @"Error %u queueing buffers (_source: %u (%p), _buffer: %u (%p))",
     234             :                                                         error, _source, &_source, _buffer, &_buffer);
     235             :                 return NO;
     236             :         }
     237             :         ALint playing = 0;
     238             :         OOAL(alGetSourcei(_source,AL_SOURCE_STATE,&playing));
     239             :         if (playing != AL_PLAYING)
     240             :         {
     241             :                 OOAL(alSourcePlay(_source));
     242             :                 if ((error = alGetError()) != AL_NO_ERROR)
     243             :                 {
     244             :                         OOLog(@"ov.debug",@"Error %d playing source",error);
     245             :                         return NO;
     246             :                 }
     247             :         }
     248             :         return YES;
     249             : }
     250             : 
     251             : 
     252             : 
     253             : - (OOSound *)sound
     254             : {
     255             :         return _sound;
     256             : }
     257             : 
     258             : @end

Generated by: LCOV version 1.14