]> git.saurik.com Git - wxWidgets.git/blobdiff - src/cocoa/sound.mm
Semicolon fixes according to Vadim's note about being danger (OW,BCC,MinGW,DMC tested).
[wxWidgets.git] / src / cocoa / sound.mm
index 8b137891791fe96927ad78e64b0aad7bded08bdc..dcfdd3acbd71f11821a1c3bc1c43a80bcb2eda80 100644 (file)
@@ -1 +1,172 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        sound.cpp
+// Purpose:     wxSound class implementation: optional
+// Author:      Ryan Norton
+// Modified by: 
+// Created:     2004-10-02
+// RCS-ID:      $Id$
+// Copyright:   (c) Ryan Norton
+// Licence:       wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
 
+#ifdef __GNUG__
+#pragma implementation "sound.h"
+#endif
+
+#include "wx/object.h"
+#include "wx/string.h"
+#include "wx/sound.h"
+
+#if wxUSE_SOUND
+
+#include "wx/app.h"
+#include "wx/cocoa/autorelease.h"
+#include "wx/cocoa/string.h"
+
+#import <AppKit/AppKit.h>
+
+//
+// NB:  Vaclav's new wxSound API is really tricky -
+// Basically, we need to make sure that if the wxSound
+// object is still in scope we don't release it's NSSound
+//
+
+WX_NSSound lastSound=NULL;
+bool isLastSoundLooping = NO;
+bool isLastSoundInScope = NO;
+
+// ========================================================================
+// wxNSSoundDelegate
+// ========================================================================
+@interface wxNSSoundDelegate : NSObject
+{
+}
+
+// Delegate methods
+- (void)sound:(NSSound *)theSound didFinishPlaying:(BOOL)bOK;
+@end // interface wxNSSoundDelegate : NSObject
+
+@implementation wxNSSoundDelegate : NSObject
+
+- (void)sound:(NSSound *)theSound didFinishPlaying:(BOOL)bOK
+{
+    if (bOK && isLastSoundLooping)
+        [lastSound play];
+    else if (isLastSoundInScope = NO)
+    {
+        [lastSound release];
+        [self release];
+    }
+}
+
+@end // wxNSSoundDelegate
+
+// ------------------------------------------------------------------
+//          wxSound
+// ------------------------------------------------------------------
+
+wxSound::wxSound()
+: m_hSnd(NULL), m_waveLength(0)
+{
+}
+
+wxSound::wxSound(const wxString& sFileName, bool isResource)
+: m_hSnd(NULL), m_waveLength(0)
+{
+    Create(sFileName, isResource);
+}
+
+wxSound::wxSound(int size, const wxByte* data)
+: m_hSnd(NULL), m_waveLength(size)
+{
+    NSData* theData = [[NSData alloc] dataWithBytesNoCopy:(void*)data length:size];
+    m_hSnd = [[NSSound alloc] initWithData:theData];
+
+    m_cocoaSoundDelegate = [[wxNSSoundDelegate alloc] init];
+}
+
+wxSound::~wxSound()
+{
+    if (m_hSnd != lastSound)
+    {
+        [m_hSnd release];
+        [m_cocoaSoundDelegate release];
+    }
+    else
+        isLastSoundInScope = NO;
+}
+
+bool wxSound::Create(const wxString& fileName, bool isResource)
+{
+    wxAutoNSAutoreleasePool thePool;
+
+    Stop();
+
+    if (isResource)
+    {
+            //oftype could be @"snd" @"wav" or @"aiff", nil or @"" autodetects (?)
+        m_hSnd = [[NSSound alloc] initWithContentsOfFile:
+            [[NSBundle mainBundle] pathForResource:wxNSStringWithWxString(fileName) ofType:nil] 
+            byReference:NO];    
+    }
+    else
+            m_hSnd = [[NSSound alloc] initWithContentsOfFile:wxNSStringWithWxString(fileName) byReference:YES];
+
+    m_cocoaSoundDelegate = [[wxNSSoundDelegate alloc] init];
+
+    m_sndname = fileName;
+    return m_hSnd != nil;
+}
+
+bool wxSound::DoPlay(unsigned flags) const
+{
+    wxASSERT_MSG(!( (flags & wxSOUND_SYNC) && (flags & wxSOUND_LOOP)), 
+                wxT("Invalid flag combination passed to wxSound::Play"));
+
+    Stop();
+
+    if (flags & wxSOUND_ASYNC)
+    {
+        lastSound = m_hSnd;
+        isLastSoundLooping = (flags & wxSOUND_LOOP) == wxSOUND_LOOP;
+        isLastSoundInScope = YES;
+       [m_hSnd setDelegate:m_cocoaSoundDelegate];
+        return [m_hSnd play];
+    }
+    else
+    {
+        [m_hSnd setDelegate:nil];
+   
+           //play until done
+        bool bOK = [m_hSnd play];
+        
+        while ([m_hSnd isPlaying]) 
+        {
+            wxTheApp->Yield(false);
+        }
+        return bOK;
+    }
+}
+
+bool wxSound::IsPlaying()
+{
+    return [lastSound isPlaying];
+}
+
+void wxSound::Stop()
+{
+    if (isLastSoundInScope)
+    {
+        isLastSoundInScope = NO;
+        
+        //remember that even though we're
+        //programatically stopping it, the
+        //delegate will still be called - 
+        //so it will free the memory here
+        [((NSSound*&)lastSound) stop];
+    }
+    
+    lastSound = nil;
+}
+
+#endif //wxUSE_SOUND