1/* 2 * Copyright (C) 2011 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27 28#if USE(COREAUDIO) 29 30#include "PlatformClockCA.h" 31 32#include <AudioToolbox/CoreAudioClock.h> 33#include <CoreAudio/AudioHardware.h> 34 35using namespace WebCore; 36 37PlatformClockCA::PlatformClockCA() 38 : m_clock(0) 39 , m_running(false) 40{ 41 CAClockNew(0, &m_clock); 42 UInt32 timebase = kCAClockTimebase_AudioDevice; 43 UInt32 timebaseSize = sizeof(timebase); 44 CAClockSetProperty(m_clock, kCAClockProperty_InternalTimebase, timebaseSize, &timebase); 45 46 AudioObjectID defaultAudioOutput = 0; 47 UInt32 defaultAudioOutputSize = sizeof(defaultAudioOutput); 48 49 AudioObjectPropertyAddress address; 50 address.mSelector = kAudioHardwarePropertyDefaultOutputDevice; 51 address.mScope = kAudioObjectPropertyScopeGlobal; 52 address.mElement = kAudioObjectPropertyElementMaster; 53 54 AudioObjectGetPropertyData(kAudioObjectSystemObject, &address, 0, 0, &defaultAudioOutputSize, &defaultAudioOutput); 55 CAClockSetProperty(m_clock, kCAClockProperty_TimebaseSource, defaultAudioOutputSize, &defaultAudioOutput); 56} 57 58PlatformClockCA::~PlatformClockCA() 59{ 60 CAClockDispose(m_clock); 61} 62 63void PlatformClockCA::setCurrentTime(double time) 64{ 65 if (m_running) 66 CAClockStop(m_clock); 67 CAClockTime caTime; 68 caTime.format = kCAClockTimeFormat_Seconds; 69 caTime.time.seconds = time; 70 CAClockSetCurrentTime(m_clock, &caTime); 71 if (m_running) 72 CAClockStart(m_clock); 73} 74 75double PlatformClockCA::currentTime() const 76{ 77 CAClockTime caTime; 78 79 // CAClock does not return the correct current time when stopped. Instead, query for 80 // what is the start time, i.e. what the current time will be when started. 81 if (m_running) { 82 if (CAClockGetCurrentTime(m_clock, kCAClockTimeFormat_Seconds, &caTime) == noErr) 83 return caTime.time.seconds; 84 } else { 85 if (CAClockGetStartTime(m_clock, kCAClockTimeFormat_Seconds, &caTime) == noErr) 86 return caTime.time.seconds; 87 } 88 return 0; 89} 90 91void PlatformClockCA::setPlayRate(double rate) 92{ 93 CAClockSetPlayRate(m_clock, rate); 94} 95 96double PlatformClockCA::PlatformClockCA::playRate() const 97{ 98 double rate = 0; 99 if (CAClockGetPlayRate(m_clock, &rate) == noErr) 100 return rate; 101 return 0; 102} 103 104void PlatformClockCA::start() 105{ 106 if (m_running) 107 return; 108 m_running = true; 109 CAClockStart(m_clock); 110} 111 112void PlatformClockCA::stop() 113{ 114 if (!m_running) 115 return; 116 m_running = false; 117 CAClockStop(m_clock); 118} 119 120 121#endif 122