src/java.desktop/macosx/native/libjsound/PLATFORM_API_MacOSX_PCM.cpp

Print this page


   1 /*
   2  * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 //#define USE_ERROR
  27 //#define USE_TRACE
  28 //#define USE_VERBOSE_TRACE
  29 
  30 #include <AudioUnit/AudioUnit.h>
  31 #include <CoreServices/CoreServices.h>
  32 #include <AudioToolbox/AudioConverter.h>
  33 #include <pthread.h>
  34 #include <math.h>
  35 /*
  36 #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
  37 #include <CoreAudio/CoreAudioTypes.h>
  38 #else
  39 #include <CoreAudioTypes.h>
  40 #endif
  41 */
  42 
  43 #include "PLATFORM_API_MacOSX_Utils.h"
  44 
  45 extern "C" {
  46 #include "Utilities.h"
  47 #include "DirectAudio.h"
  48 }
  49 
  50 #if USE_DAUDIO == TRUE
  51 


 600 };
 601 
 602 
 603 struct OSX_DirectAudioDevice {
 604     AudioUnit   audioUnit;
 605     RingBuffer  ringBuffer;
 606     AudioStreamBasicDescription asbd;
 607 
 608     // only for target lines
 609     UInt32      inputBufferSizeInBytes;
 610     Resampler   *resampler;
 611     // to detect discontinuity (to reset resampler)
 612     SInt64      lastWrittenSampleTime;
 613 
 614 
 615     OSX_DirectAudioDevice() : audioUnit(NULL), asbd(), resampler(NULL), lastWrittenSampleTime(0) {
 616     }
 617 
 618     ~OSX_DirectAudioDevice() {
 619         if (audioUnit) {
 620             CloseComponent(audioUnit);
 621         }
 622         if (resampler) {
 623             delete resampler;
 624         }
 625     }
 626 };
 627 
 628 static AudioUnit CreateOutputUnit(AudioDeviceID deviceID, int isSource)
 629 {
 630     OSStatus err;
 631     AudioUnit unit;
 632     UInt32 size;
 633 
 634     ComponentDescription desc;
 635     desc.componentType         = kAudioUnitType_Output;
 636     desc.componentSubType      = (deviceID == 0 && isSource) ? kAudioUnitSubType_DefaultOutput : kAudioUnitSubType_HALOutput;
 637     desc.componentManufacturer = kAudioUnitManufacturer_Apple;
 638     desc.componentFlags        = 0;
 639     desc.componentFlagsMask    = 0;
 640 
 641     Component comp = FindNextComponent(NULL, &desc);
 642     err = OpenAComponent(comp, &unit);
 643 
 644     if (err) {
 645         OS_ERROR0(err, "CreateOutputUnit:OpenAComponent");
 646         return NULL;
 647     }
 648 
 649     if (!isSource) {
 650         int enableIO = 0;
 651         err = AudioUnitSetProperty(unit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output,
 652                                     0, &enableIO, sizeof(enableIO));
 653         if (err) {
 654             OS_ERROR0(err, "SetProperty (output EnableIO)");
 655         }
 656         enableIO = 1;
 657         err = AudioUnitSetProperty(unit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input,
 658                                     1, &enableIO, sizeof(enableIO));
 659         if (err) {
 660             OS_ERROR0(err, "SetProperty (input EnableIO)");
 661         }
 662 
 663         if (!deviceID) {
 664             // get real AudioDeviceID for default input device (macosx current input device)
 665             deviceID = GetDefaultDevice(isSource);
 666             if (!deviceID) {
 667                 CloseComponent(unit);
 668                 return NULL;
 669             }
 670         }
 671     }
 672 
 673     if (deviceID) {
 674         err = AudioUnitSetProperty(unit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global,
 675                                     0, &deviceID, sizeof(deviceID));
 676         if (err) {
 677             OS_ERROR0(err, "SetProperty (CurrentDevice)");
 678             CloseComponent(unit);
 679             return NULL;
 680         }
 681     }
 682 
 683     return unit;
 684 }
 685 
 686 static OSStatus OutputCallback(void                         *inRefCon,
 687                                AudioUnitRenderActionFlags   *ioActionFlags,
 688                                const AudioTimeStamp         *inTimeStamp,
 689                                UInt32                       inBusNumber,
 690                                UInt32                       inNumberFrames,
 691                                AudioBufferList              *ioData)
 692 {
 693     OSX_DirectAudioDevice *device = (OSX_DirectAudioDevice*)inRefCon;
 694 
 695     int nchannels = ioData->mNumberBuffers; // should be always == 1 (interleaved channels)
 696     AudioBuffer *audioBuffer = ioData->mBuffers;
 697 
 698     TRACE3(">>OutputCallback: busNum=%d, requested %d frames (%d bytes)\n",


   1 /*
   2  * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 //#define USE_ERROR
  27 //#define USE_TRACE
  28 //#define USE_VERBOSE_TRACE
  29 
  30 #include <AudioUnit/AudioUnit.h>

  31 #include <AudioToolbox/AudioConverter.h>
  32 #include <pthread.h>
  33 #include <math.h>
  34 /*
  35 #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
  36 #include <CoreAudio/CoreAudioTypes.h>
  37 #else
  38 #include <CoreAudioTypes.h>
  39 #endif
  40 */
  41 
  42 #include "PLATFORM_API_MacOSX_Utils.h"
  43 
  44 extern "C" {
  45 #include "Utilities.h"
  46 #include "DirectAudio.h"
  47 }
  48 
  49 #if USE_DAUDIO == TRUE
  50 


 599 };
 600 
 601 
 602 struct OSX_DirectAudioDevice {
 603     AudioUnit   audioUnit;
 604     RingBuffer  ringBuffer;
 605     AudioStreamBasicDescription asbd;
 606 
 607     // only for target lines
 608     UInt32      inputBufferSizeInBytes;
 609     Resampler   *resampler;
 610     // to detect discontinuity (to reset resampler)
 611     SInt64      lastWrittenSampleTime;
 612 
 613 
 614     OSX_DirectAudioDevice() : audioUnit(NULL), asbd(), resampler(NULL), lastWrittenSampleTime(0) {
 615     }
 616 
 617     ~OSX_DirectAudioDevice() {
 618         if (audioUnit) {
 619             AudioComponentInstanceDispose(audioUnit);
 620         }
 621         if (resampler) {
 622             delete resampler;
 623         }
 624     }
 625 };
 626 
 627 static AudioUnit CreateOutputUnit(AudioDeviceID deviceID, int isSource)
 628 {
 629     OSStatus err;
 630     AudioUnit unit;

 631 
 632     AudioComponentDescription desc;
 633     desc.componentType         = kAudioUnitType_Output;
 634     desc.componentSubType      = (deviceID == 0 && isSource) ? kAudioUnitSubType_DefaultOutput : kAudioUnitSubType_HALOutput;
 635     desc.componentManufacturer = kAudioUnitManufacturer_Apple;
 636     desc.componentFlags        = 0;
 637     desc.componentFlagsMask    = 0;
 638 
 639     AudioComponent comp = AudioComponentFindNext(NULL, &desc);
 640     err = AudioComponentInstanceNew(comp, &unit);
 641 
 642     if (err) {
 643         OS_ERROR0(err, "CreateOutputUnit:OpenAComponent");
 644         return NULL;
 645     }
 646 
 647     if (!isSource) {
 648         int enableIO = 0;
 649         err = AudioUnitSetProperty(unit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output,
 650                                     0, &enableIO, sizeof(enableIO));
 651         if (err) {
 652             OS_ERROR0(err, "SetProperty (output EnableIO)");
 653         }
 654         enableIO = 1;
 655         err = AudioUnitSetProperty(unit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input,
 656                                     1, &enableIO, sizeof(enableIO));
 657         if (err) {
 658             OS_ERROR0(err, "SetProperty (input EnableIO)");
 659         }
 660 
 661         if (!deviceID) {
 662             // get real AudioDeviceID for default input device (macosx current input device)
 663             deviceID = GetDefaultDevice(isSource);
 664             if (!deviceID) {
 665                 AudioComponentInstanceDispose(unit);
 666                 return NULL;
 667             }
 668         }
 669     }
 670 
 671     if (deviceID) {
 672         err = AudioUnitSetProperty(unit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global,
 673                                     0, &deviceID, sizeof(deviceID));
 674         if (err) {
 675             OS_ERROR0(err, "SetProperty (CurrentDevice)");
 676             AudioComponentInstanceDispose(unit);
 677             return NULL;
 678         }
 679     }
 680 
 681     return unit;
 682 }
 683 
 684 static OSStatus OutputCallback(void                         *inRefCon,
 685                                AudioUnitRenderActionFlags   *ioActionFlags,
 686                                const AudioTimeStamp         *inTimeStamp,
 687                                UInt32                       inBusNumber,
 688                                UInt32                       inNumberFrames,
 689                                AudioBufferList              *ioData)
 690 {
 691     OSX_DirectAudioDevice *device = (OSX_DirectAudioDevice*)inRefCon;
 692 
 693     int nchannels = ioData->mNumberBuffers; // should be always == 1 (interleaved channels)
 694     AudioBuffer *audioBuffer = ioData->mBuffers;
 695 
 696     TRACE3(">>OutputCallback: busNum=%d, requested %d frames (%d bytes)\n",