Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tsound_t.h"
Toshihiro Shimizu 890ddd
#include "texception.h"
Toshihiro Shimizu 890ddd
#include "tthread.h"
Toshihiro Shimizu 890ddd
#include "tthreadmessage.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <errno.h></errno.h>
Toshihiro Shimizu 890ddd
#include <unistd.h></unistd.h>
Toshihiro Shimizu 890ddd
#include <queue></queue>
Toshihiro Shimizu 890ddd
#include <set></set>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <coreservices coreservices.h=""></coreservices>
Toshihiro Shimizu 890ddd
#include <audiounit audiounit.h=""></audiounit>
Toshihiro Shimizu 890ddd
#include <coreaudio coreaudio.h=""></coreaudio>
Toshihiro Shimizu 890ddd
#include <audiotoolbox audiotoolbox.h=""></audiotoolbox>
Toshihiro Shimizu 890ddd
using namespace std;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
TThread::Mutex MutexOut;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class TSoundOutputDeviceImp
Shinya Kitaoka 120a6e
    : public std::enable_shared_from_this<tsoundoutputdeviceimp> {</tsoundoutputdeviceimp>
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  bool m_isPlaying;
Shinya Kitaoka 120a6e
  bool m_looped;
Shinya Kitaoka 120a6e
  TSoundTrackFormat m_currentFormat;
Shinya Kitaoka 120a6e
  std::set<int> m_supportedRate;</int>
Shinya Kitaoka 120a6e
  bool m_opened;
Shinya Kitaoka 120a6e
  AudioFileID musicFileID;
Shinya Kitaoka 120a6e
  AudioUnit theOutputUnit;
Shinya Kitaoka 120a6e
  AudioStreamBasicDescription fileASBD;
Shinya Kitaoka 120a6e
  AudioStreamBasicDescription outputASBD;
Shinya Kitaoka 120a6e
  AudioConverterRef converter;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TSoundOutputDeviceImp()
Shinya Kitaoka 120a6e
      : m_isPlaying(false)
Shinya Kitaoka 120a6e
      , m_looped(false)
Shinya Kitaoka 120a6e
      , m_supportedRate()
Shinya Kitaoka 120a6e
      , m_opened(false){};
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::set<tsoundoutputdevicelistener *=""> m_listeners;</tsoundoutputdevicelistener>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ~TSoundOutputDeviceImp(){};
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool doOpenDevice();
Shinya Kitaoka 120a6e
  bool doSetStreamFormat(const TSoundTrackFormat &format);
Shinya Kitaoka 120a6e
  bool doStopDevice();
Shinya Kitaoka 120a6e
  void play(const TSoundTrackP &st, TINT32 s0, TINT32 s1, bool loop,
Shinya Kitaoka 120a6e
            bool scrubbing);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct MyData {
Shinya Kitaoka 120a6e
  char *entireFileBuffer;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  UInt64 totalPacketCount;
Shinya Kitaoka 120a6e
  UInt64 fileByteCount;
Shinya Kitaoka 120a6e
  UInt32 maxPacketSize;
Shinya Kitaoka 120a6e
  UInt64 packetOffset;
Shinya Kitaoka 120a6e
  UInt64 byteOffset;
Shinya Kitaoka 120a6e
  bool m_doNotify;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void *sourceBuffer;
Shinya Kitaoka 120a6e
  AudioConverterRef converter;
Shinya Kitaoka 120a6e
  std::shared_ptr<tsoundoutputdeviceimp> imp;</tsoundoutputdeviceimp>
Shinya Kitaoka 120a6e
  bool isLooping;
Shinya Kitaoka 120a6e
  MyData()
Shinya Kitaoka 120a6e
      : entireFileBuffer(0)
Shinya Kitaoka 120a6e
      , totalPacketCount(0)
Shinya Kitaoka 120a6e
      , fileByteCount(0)
Shinya Kitaoka 120a6e
      , maxPacketSize(0)
Shinya Kitaoka 120a6e
      , packetOffset(0)
Shinya Kitaoka 120a6e
      , byteOffset(0)
Shinya Kitaoka 120a6e
      , sourceBuffer(0)
Shinya Kitaoka 120a6e
      , isLooping(false)
Shinya Kitaoka 120a6e
      , m_doNotify(true) {}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class PlayCompletedMsg : public TThread::Message {
Shinya Kitaoka 120a6e
  std::set<tsoundoutputdevicelistener *=""> m_listeners;</tsoundoutputdevicelistener>
Shinya Kitaoka 120a6e
  MyData *m_data;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  PlayCompletedMsg(MyData *data) : m_data(data) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TThread::Message *clone() const { return new PlayCompletedMsg(*this); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void onDeliver() {
Shinya Kitaoka 120a6e
    if (m_data->imp) {
Shinya Kitaoka 120a6e
      if (m_data->m_doNotify == false) return;
Shinya Kitaoka 120a6e
      m_data->m_doNotify = false;
Shinya Kitaoka 120a6e
      if (m_data->imp->m_isPlaying) m_data->imp->doStopDevice();
Shinya Kitaoka 120a6e
      std::set<tsoundoutputdevicelistener *="">::iterator it =</tsoundoutputdevicelistener>
Shinya Kitaoka 120a6e
          m_data->imp->m_listeners.begin();
Shinya Kitaoka 120a6e
      for (; it != m_data->imp->m_listeners.end(); ++it)
Shinya Kitaoka 120a6e
        (*it)->onPlayCompleted();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#define checkStatus(err)                                                       \
Shinya Kitaoka 120a6e
  if (err) {                                                                   \
Shinya Kitaoka 120a6e
    printf("Error: 0x%x ->  %s: %d\n", (int)err, __FILE__, __LINE__);          \
Shinya Kitaoka 120a6e
    fflush(stdout);                                                            \
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
extern "C" {
Shinya Kitaoka 120a6e
// This is an example of a Input Procedure from a call to
Shinya Kitaoka 120a6e
// AudioConverterFillComplexBuffer.
Shinya Kitaoka 120a6e
// The total amount of data needed is "ioNumberDataPackets" when this method is
Shinya Kitaoka 120a6e
// first called.
Shinya Kitaoka 120a6e
// On exit, "ioNumberDataPackets" must be set to the actual amount of data
Shinya Kitaoka 120a6e
// obtained.
Shinya Kitaoka 120a6e
// Upon completion, all new input data must point to the AudioBufferList in the
Shinya Kitaoka 120a6e
// parameter ( "ioData" )
Shinya Kitaoka 120a6e
OSStatus MyACComplexInputProc(
Shinya Kitaoka 120a6e
    AudioConverterRef inAudioConverter, UInt32 *ioNumberDataPackets,
Shinya Kitaoka 120a6e
    AudioBufferList *ioData,
Shinya Kitaoka 120a6e
    AudioStreamPacketDescription **outDataPacketDescription, void *inUserData) {
Shinya Kitaoka 120a6e
  OSStatus err       = noErr;
Shinya Kitaoka 120a6e
  UInt32 bytesCopied = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  MyData *myData = static_cast<mydata *="">(inUserData);</mydata>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // initialize in case of failure
Shinya Kitaoka 120a6e
  ioData->mBuffers[0].mData         = NULL;
Shinya Kitaoka 120a6e
  ioData->mBuffers[0].mDataByteSize = 0;
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
  {
Shinya Kitaoka 120a6e
    // TThread::ScopedLock sl(MutexOut);
Shinya Kitaoka 120a6e
    if (myData->imp->m_isPlaying == false) return noErr;
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // if there are not enough packets to satisfy request, then read what's left
Shinya Kitaoka 120a6e
  if (myData->packetOffset + *ioNumberDataPackets > myData->totalPacketCount)
Shinya Kitaoka 120a6e
    *ioNumberDataPackets = myData->totalPacketCount - myData->packetOffset;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // do nothing if there are no packets available
Shinya Kitaoka 120a6e
  if (*ioNumberDataPackets) {
Shinya Kitaoka 120a6e
    if (myData->sourceBuffer != NULL) {
Shinya Kitaoka 120a6e
      free(myData->sourceBuffer);
Shinya Kitaoka 120a6e
      myData->sourceBuffer = NULL;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // the total amount of data requested by the AudioConverter
Shinya Kitaoka 120a6e
    bytesCopied = *ioNumberDataPackets * myData->maxPacketSize;
Shinya Kitaoka 120a6e
    // alloc a small buffer for the AudioConverter to use.
Shinya Kitaoka 120a6e
    myData->sourceBuffer = (void *)calloc(1, bytesCopied);
Shinya Kitaoka 120a6e
    // copy the amount of data needed (bytesCopied) from buffer of audio file
Shinya Kitaoka 120a6e
    memcpy(myData->sourceBuffer, myData->entireFileBuffer + myData->byteOffset,
Shinya Kitaoka 120a6e
           bytesCopied);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // keep track of where we want to read from next time
Shinya Kitaoka 120a6e
    myData->byteOffset += *ioNumberDataPackets * myData->maxPacketSize;
Shinya Kitaoka 120a6e
    myData->packetOffset += *ioNumberDataPackets;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    ioData->mBuffers[0].mData = myData->sourceBuffer;  // tell the Audio
Shinya Kitaoka 120a6e
                                                       // Converter where it's
Shinya Kitaoka 120a6e
                                                       // source data is
Shinya Kitaoka 120a6e
    ioData->mBuffers[0].mDataByteSize =
Shinya Kitaoka 120a6e
        bytesCopied;  // tell the Audio Converter how much data in each buffer
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    // there aren't any more packets to read.
Shinya Kitaoka 120a6e
    // Set the amount of data read (mDataByteSize) to zero
Shinya Kitaoka 120a6e
    // and return noErr to signal the AudioConverter there are
Shinya Kitaoka 120a6e
    // no packets left.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    ioData->mBuffers[0].mData         = NULL;
Shinya Kitaoka 120a6e
    ioData->mBuffers[0].mDataByteSize = 0;
Shinya Kitaoka 120a6e
    delete[] myData->entireFileBuffer;
Shinya Kitaoka 120a6e
    myData->entireFileBuffer = 0;
Shinya Kitaoka 120a6e
    err                      = noErr;
Shinya Kitaoka 120a6e
    /*
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
TThread::ScopedLock sl(MutexOut);
Shinya Kitaoka 120a6e
*(myData->isPlaying) = false;   //questo lo faccio nel main thread
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
    PlayCompletedMsg(myData).send();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return err;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
OSStatus MyFileRenderProc(void *inRefCon,
Shinya Kitaoka 120a6e
                          AudioUnitRenderActionFlags *inActionFlags,
Shinya Kitaoka 120a6e
                          const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber,
Shinya Kitaoka 120a6e
                          UInt32 inNumFrames, AudioBufferList *ioData) {
Shinya Kitaoka 120a6e
  MyData *myData                = static_cast<mydata *="">(inRefCon);</mydata>
Shinya Kitaoka 120a6e
  OSStatus err                  = noErr;
Shinya Kitaoka 120a6e
  void *inInputDataProcUserData = inRefCon;
Shinya Kitaoka 120a6e
  AudioStreamPacketDescription *outPacketDescription = NULL;
Shinya Kitaoka 120a6e
  // To obtain a data buffer of converted data from a complex input
Shinya Kitaoka 120a6e
  // source(compressed files, etc.)
Shinya Kitaoka 120a6e
  // use AudioConverterFillComplexBuffer.  The total amount of data requested is
Shinya Kitaoka 120a6e
  // "inNumFrames" and
Shinya Kitaoka 120a6e
  // on return is set to the actual amount of data recieved.
Shinya Kitaoka 120a6e
  // All converted data is returned to "ioData" (AudioBufferList).
Shinya Kitaoka 120a6e
  err = AudioConverterFillComplexBuffer(myData->converter, MyACComplexInputProc,
Shinya Kitaoka 120a6e
                                        inInputDataProcUserData, &inNumFrames,
Shinya Kitaoka 120a6e
                                        ioData, outPacketDescription);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*Parameters for AudioConverterFillComplexBuffer()
Toshihiro Shimizu 890ddd
converter - the converter being used
Toshihiro Shimizu 890ddd
ACComplexInputProc() - input procedure to supply data to the Audio Converter
Shinya Kitaoka 120a6e
inInputDataProcUserData - Used to hold any data that needs to be passed on.  Not
Shinya Kitaoka 120a6e
needed in this example.
Toshihiro Shimizu 890ddd
inNumFrames - The amount of requested data.  On output, this
Toshihiro Shimizu 890ddd
number is the amount actually received.
Toshihiro Shimizu 890ddd
ioData - Buffer of the converted data recieved on return
Shinya Kitaoka 120a6e
outPacketDescription - contains the format of the returned data.  Not used in
Shinya Kitaoka 120a6e
this example.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // checkStatus(err);
Shinya Kitaoka 120a6e
  return err;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // extern "C"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void PrintStreamDesc(AudioStreamBasicDescription *inDesc) {
Shinya Kitaoka 120a6e
  if (!inDesc) {
Shinya Kitaoka 120a6e
    printf("Can't print a NULL desc!\n");
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  printf("- - - - - - - - - - - - - - - - - - - -\n");
Shinya Kitaoka 120a6e
  printf("  Sample Rate:%f\n", inDesc->mSampleRate);
Shinya Kitaoka 120a6e
  printf("  Format ID:%.*s\n", (int)sizeof(inDesc->mFormatID),
Shinya Kitaoka 120a6e
         (char *)&inDesc->mFormatID);
Shinya Kitaoka 120a6e
  printf("  Format Flags:%lX\n", inDesc->mFormatFlags);
Shinya Kitaoka 120a6e
  printf("  Bytes per Packet:%ld\n", inDesc->mBytesPerPacket);
Shinya Kitaoka 120a6e
  printf("  Frames per Packet:%ld\n", inDesc->mFramesPerPacket);
Shinya Kitaoka 120a6e
  printf("  Bytes per Frame:%ld\n", inDesc->mBytesPerFrame);
Shinya Kitaoka 120a6e
  printf("  Channels per Frame:%ld\n", inDesc->mChannelsPerFrame);
Shinya Kitaoka 120a6e
  printf("  Bits per Channel:%ld\n", inDesc->mBitsPerChannel);
Shinya Kitaoka 120a6e
  printf("- - - - - - - - - - - - - - - - - - - -\n");
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
bool TSoundOutputDeviceImp::doOpenDevice() {
Shinya Kitaoka 120a6e
  m_opened     = false;
Shinya Kitaoka 120a6e
  OSStatus err = noErr;
Shinya Kitaoka 120a6e
  ComponentDescription desc;
Shinya Kitaoka 120a6e
  Component comp;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  desc.componentType    = kAudioUnitType_Output;
Shinya Kitaoka 120a6e
  desc.componentSubType = kAudioUnitSubType_DefaultOutput;
Shinya Kitaoka 120a6e
  // all Audio Units in AUComponent.h must use "kAudioUnitManufacturer_Apple" as
Shinya Kitaoka 120a6e
  // the Manufacturer
Shinya Kitaoka 120a6e
  desc.componentManufacturer = kAudioUnitManufacturer_Apple;
Shinya Kitaoka 120a6e
  desc.componentFlags        = 0;
Shinya Kitaoka 120a6e
  desc.componentFlagsMask    = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  comp = FindNextComponent(
Shinya Kitaoka 120a6e
      NULL, &desc);  // Finds an component that meets the desc spec's
Shinya Kitaoka 120a6e
  if (comp == NULL) return false;
Shinya Kitaoka 120a6e
  err = OpenAComponent(comp, &theOutputUnit);  // gains access to the services
Shinya Kitaoka 120a6e
                                               // provided by the component
Shinya Kitaoka 120a6e
  if (err) return false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  UInt32 size;
Shinya Kitaoka 120a6e
  Boolean outWritable;
Shinya Kitaoka 120a6e
  UInt32 theInputBus = 0;
Shinya Kitaoka 120a6e
  // Gets the size of the Stream Format Property and if it is writable
Shinya Kitaoka 120a6e
  err =
Shinya Kitaoka 120a6e
      AudioUnitGetPropertyInfo(theOutputUnit, kAudioUnitProperty_StreamFormat,
Shinya Kitaoka 120a6e
                               kAudioUnitScope_Output, 0, &size, &outWritable);
Shinya Kitaoka 120a6e
  // Get the current stream format of the output
Shinya Kitaoka 120a6e
  err = AudioUnitGetProperty(theOutputUnit, kAudioUnitProperty_StreamFormat,
Shinya Kitaoka 120a6e
                             kAudioUnitScope_Output, 0, &outputASBD, &size);
Shinya Kitaoka 120a6e
  checkStatus(err);
Shinya Kitaoka 120a6e
  // Set the stream format of the output to match the input
Shinya Kitaoka 120a6e
  err = AudioUnitSetProperty(theOutputUnit, kAudioUnitProperty_StreamFormat,
Shinya Kitaoka 120a6e
                             kAudioUnitScope_Input, theInputBus, &outputASBD,
Shinya Kitaoka 120a6e
                             size);
Shinya Kitaoka 120a6e
  checkStatus(err);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Initialize AudioUnit, alloc mem buffers for processing
Shinya Kitaoka 120a6e
  err = AudioUnitInitialize(theOutputUnit);
Shinya Kitaoka 120a6e
  checkStatus(err);
Shinya Kitaoka 120a6e
  if (err == noErr) m_opened = true;
Shinya Kitaoka 120a6e
  return m_opened;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
bool TSoundOutputDeviceImp::doSetStreamFormat(const TSoundTrackFormat &format) {
Shinya Kitaoka 120a6e
  if (!m_opened) doOpenDevice();
Shinya Kitaoka 120a6e
  if (!m_opened) return false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  fileASBD.mSampleRate  = format.m_sampleRate;
Shinya Kitaoka 120a6e
  fileASBD.mFormatID    = kAudioFormatLinearPCM;
Shinya Kitaoka 120a6e
  fileASBD.mFormatFlags = 14;
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
Standard flags: kAudioFormatFlagIsFloat = (1L << 0)
Toshihiro Shimizu 890ddd
kAudioFormatFlagIsBigEndian = (1L << 1)
Toshihiro Shimizu 890ddd
kAudioFormatFlagIsSignedInteger = (1L << 2)
Toshihiro Shimizu 890ddd
kAudioFormatFlagIsPacked = (1L << 3)
Toshihiro Shimizu 890ddd
kAudioFormatFlagIsAlignedHigh = (1L << 4)
Toshihiro Shimizu 890ddd
kAudioFormatFlagIsNonInterleaved = (1L << 5)
Toshihiro Shimizu 890ddd
kAudioFormatFlagsAreAllClear = (1L << 31)
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
Linear PCM flags:
Toshihiro Shimizu 890ddd
kLinearPCMFormatFlagIsFloat = kAudioFormatFlagIsFloat
Toshihiro Shimizu 890ddd
kLinearPCMFormatFlagIsBigEndian = kAudioFormatFlagIsBigEndian
Toshihiro Shimizu 890ddd
kLinearPCMFormatFlagIsSignedInteger = kAudioFormatFlagIsSignedInteger
Toshihiro Shimizu 890ddd
kLinearPCMFormatFlagIsPacked = kAudioFormatFlagIsPacked
Toshihiro Shimizu 890ddd
kLinearPCMFormatFlagIsAlignedHigh = kAudioFormatFlagIsAlignedHigh
Toshihiro Shimizu 890ddd
kLinearPCMFormatFlagIsNonInterleaved = kAudioFormatFlagIsNonInterleaved
Shinya Kitaoka 120a6e
kLinearPCMFormatFlagsAreAllClear = kAudioFormatFlagsAreAllClear
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
  fileASBD.mBytesPerPacket =
Shinya Kitaoka 120a6e
      (format.m_bitPerSample >> 3) * format.m_channelCount;
Shinya Kitaoka 120a6e
  fileASBD.mFramesPerPacket = 1;
Shinya Kitaoka 120a6e
  fileASBD.mBytesPerFrame =
Shinya Kitaoka 120a6e
      (format.m_bitPerSample >> 3) * format.m_channelCount;
Shinya Kitaoka 120a6e
  fileASBD.mChannelsPerFrame = format.m_channelCount;
Shinya Kitaoka 120a6e
  fileASBD.mBitsPerChannel   = format.m_bitPerSample;
Shinya Kitaoka 120a6e
  fileASBD.mReserved         = 0;
Shinya Kitaoka 120a6e
  // PrintStreamDesc(&fileASBD);
Shinya Kitaoka 120a6e
  m_opened = true;
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TSoundOutputDevice::TSoundOutputDevice() : m_imp(new TSoundOutputDeviceImp) {
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    supportsVolume();
Shinya Kitaoka 120a6e
  } catch (TSoundDeviceException &e) {
Shinya Kitaoka 120a6e
    throw TSoundDeviceException(e.getType(), e.getMessage());
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TSoundOutputDevice::~TSoundOutputDevice() {
Shinya Kitaoka 120a6e
  stop();
Shinya Kitaoka 120a6e
  close();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TSoundOutputDevice::installed() { return true; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TSoundOutputDevice::open(const TSoundTrackP &st) {
Shinya Kitaoka 120a6e
  if (!m_imp->doOpenDevice())
Shinya Kitaoka 120a6e
    throw TSoundDeviceException(TSoundDeviceException::UnableOpenDevice,
Shinya Kitaoka 120a6e
                                "Problem to open the output device");
Shinya Kitaoka 120a6e
  if (!m_imp->doSetStreamFormat(st->getFormat()))
Shinya Kitaoka 120a6e
    throw TSoundDeviceException(
Shinya Kitaoka 120a6e
        TSoundDeviceException::UnableOpenDevice,
Shinya Kitaoka 120a6e
        "Problem to open the output device setting some params");
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TSoundOutputDevice::close() {
Shinya Kitaoka 120a6e
  stop();
Shinya Kitaoka 120a6e
  m_imp->m_opened = false;
Shinya Kitaoka 120a6e
  AudioUnitUninitialize(
Shinya Kitaoka 120a6e
      m_imp->theOutputUnit);  // release resources without closing the component
Shinya Kitaoka 120a6e
  CloseComponent(m_imp->theOutputUnit);  // Terminates your application's access
Shinya Kitaoka 120a6e
                                         // to the services provided
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TSoundOutputDevice::play(const TSoundTrackP &st, TINT32 s0, TINT32 s1,
Shinya Kitaoka 120a6e
                              bool loop, bool scrubbing) {
Shinya Kitaoka 120a6e
  // TThread::ScopedLock sl(MutexOut);
Shinya Kitaoka 120a6e
  int lastSample = st->getSampleCount() - 1;
Shinya Kitaoka 120a6e
  notLessThan(0, s0);
Shinya Kitaoka 120a6e
  notLessThan(0, s1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  notMoreThan(lastSample, s0);
Shinya Kitaoka 120a6e
  notMoreThan(lastSample, s1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (s0 > s1) {
Toshihiro Shimizu 890ddd
#ifdef DEBUG
Shinya Kitaoka 120a6e
    cout << "s0 > s1; reorder" << endl;
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    swap(s0, s1);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (isPlaying()) {
Toshihiro Shimizu 890ddd
#ifdef DEBUG
Shinya Kitaoka 120a6e
    cout << "is playing, stop it!" << endl;
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    stop();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  m_imp->play(st, s0, s1, loop, scrubbing);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TSoundOutputDeviceImp::play(const TSoundTrackP &st, TINT32 s0, TINT32 s1,
Shinya Kitaoka 120a6e
                                 bool loop, bool scrubbing) {
Shinya Kitaoka 120a6e
  if (!doSetStreamFormat(st->getFormat())) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  OSStatus err   = noErr;
Shinya Kitaoka 120a6e
  MyData *myData = new MyData();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  myData->imp            = shared_from_this();
Shinya Kitaoka 120a6e
  UInt32 magicCookieSize = 0;
Shinya Kitaoka 120a6e
  // PrintStreamDesc(&outputASBD);
Shinya Kitaoka 120a6e
  err = AudioConverterNew(&fileASBD, &outputASBD, &converter);
Shinya Kitaoka 120a6e
  checkStatus(err);
Shinya Kitaoka 120a6e
  err = AudioFileGetPropertyInfo(musicFileID, kAudioFilePropertyMagicCookieData,
Shinya Kitaoka 120a6e
                                 &magicCookieSize, NULL);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (err == noErr) {
Shinya Kitaoka 120a6e
    void *magicCookie = calloc(1, magicCookieSize);
Shinya Kitaoka 120a6e
    if (magicCookie) {
Shinya Kitaoka 120a6e
      // Get Magic Cookie data from Audio File
Shinya Kitaoka 120a6e
      err = AudioFileGetProperty(musicFileID, kAudioFilePropertyMagicCookieData,
Shinya Kitaoka 120a6e
                                 &magicCookieSize, magicCookie);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // Give the AudioConverter the magic cookie decompression params if there
Shinya Kitaoka 120a6e
      // are any
Shinya Kitaoka 120a6e
      if (err == noErr) {
Shinya Kitaoka 120a6e
        err = AudioConverterSetProperty(myData->converter,
Shinya Kitaoka 120a6e
                                        kAudioConverterDecompressionMagicCookie,
Shinya Kitaoka 120a6e
                                        magicCookieSize, magicCookie);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      err = noErr;
Shinya Kitaoka 120a6e
      if (magicCookie) free(magicCookie);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else  // this is OK because some audio data doesn't need magic cookie data
Shinya Kitaoka 120a6e
    err = noErr;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  checkStatus(err);
Shinya Kitaoka 120a6e
  myData->converter        = converter;
Shinya Kitaoka 120a6e
  myData->totalPacketCount = s1 - s0;
Shinya Kitaoka 120a6e
  myData->fileByteCount    = (s1 - s0) * st->getSampleSize();
Shinya Kitaoka 120a6e
  myData->entireFileBuffer = new char[myData->fileByteCount];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#if defined(i386)
Shinya Kitaoka 120a6e
  if (st->getBitPerSample() == 16) {
Shinya Kitaoka 120a6e
    int i;
Shinya Kitaoka 120a6e
    USHORT *dst = (USHORT *)(myData->entireFileBuffer);
Shinya Kitaoka 120a6e
    USHORT *src = (USHORT *)(st->getRawData() + s0 * st->getSampleSize());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (i = 0; i < myData->fileByteCount / 2; i++) *dst++ = swapUshort(*src++);
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    memcpy(myData->entireFileBuffer,
Shinya Kitaoka 120a6e
           st->getRawData() + s0 * st->getSampleSize(), myData->fileByteCount);
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
  memcpy(myData->entireFileBuffer, st->getRawData() + s0 * st->getSampleSize(),
Shinya Kitaoka 120a6e
         myData->fileByteCount);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  myData->maxPacketSize = fileASBD.mFramesPerPacket * fileASBD.mBytesPerFrame;
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    // TThread::ScopedLock sl(MutexOut);
Shinya Kitaoka 120a6e
    m_isPlaying = true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  myData->isLooping = loop;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // cout << "total packet count = " << myData->totalPacketCount <
Shinya Kitaoka 120a6e
  // cout << "filebytecount " << myData->fileByteCount << endl;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  AURenderCallbackStruct renderCallback;
Shinya Kitaoka 120a6e
  memset(&renderCallback, 0, sizeof(AURenderCallbackStruct));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  renderCallback.inputProc       = MyFileRenderProc;
Shinya Kitaoka 120a6e
  renderCallback.inputProcRefCon = myData;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Sets the callback for the Audio Unit to the renderCallback
Shinya Kitaoka 120a6e
  err =
Shinya Kitaoka 120a6e
      AudioUnitSetProperty(theOutputUnit, kAudioUnitProperty_SetRenderCallback,
Shinya Kitaoka 120a6e
                           kAudioUnitScope_Input, 0, &renderCallback,
Shinya Kitaoka 120a6e
                           sizeof(AURenderCallbackStruct));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  checkStatus(err);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  err = AudioOutputUnitStart(theOutputUnit);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  checkStatus(err);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TSoundOutputDeviceImp::doStopDevice() {
Shinya Kitaoka 120a6e
  m_isPlaying = false;
Shinya Kitaoka 120a6e
  AudioOutputUnitStop(
Shinya Kitaoka 120a6e
      theOutputUnit);  // you must stop the audio unit from processing
Shinya Kitaoka 120a6e
  AudioConverterDispose(
Shinya Kitaoka 120a6e
      converter);  // deallocates the memory used by inAudioConverter
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TSoundOutputDevice::stop() {
Shinya Kitaoka 120a6e
  // TThread::ScopedLock sl(MutexOut);
Shinya Kitaoka 120a6e
  if (m_imp->m_opened == false) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // TThread::ScopedLock sl(MutexOut);
Shinya Kitaoka 120a6e
  m_imp->doStopDevice();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TSoundOutputDevice::attach(TSoundOutputDeviceListener *listener) {
Shinya Kitaoka 120a6e
  m_imp->m_listeners.insert(listener);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TSoundOutputDevice::detach(TSoundOutputDeviceListener *listener) {
Shinya Kitaoka 120a6e
  m_imp->m_listeners.erase(listener);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
double TSoundOutputDevice::getVolume() {
Shinya Kitaoka 120a6e
  if (!m_imp->m_opened) m_imp->doOpenDevice();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  Float32 leftVol, rightVol;
Shinya Kitaoka 120a6e
  AudioUnitGetParameter(m_imp->theOutputUnit, kHALOutputParam_Volume,
Shinya Kitaoka 120a6e
                        kAudioUnitScope_Output, 0, &leftVol);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  AudioUnitGetParameter(m_imp->theOutputUnit, kHALOutputParam_Volume,
Shinya Kitaoka 120a6e
                        kAudioUnitScope_Output, 0, &rightVol);
Shinya Kitaoka 120a6e
  double vol = (leftVol + rightVol) / 2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return (vol < 0. ? 0. : vol);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TSoundOutputDevice::setVolume(double volume) {
Shinya Kitaoka 120a6e
  Float32 vol = volume;
Shinya Kitaoka 120a6e
  AudioUnitSetParameter(m_imp->theOutputUnit, kHALOutputParam_Volume,
Shinya Kitaoka 120a6e
                        kAudioUnitScope_Output, 0, vol, 0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  AudioUnitSetParameter(m_imp->theOutputUnit, kHALOutputParam_Volume,
Shinya Kitaoka 120a6e
                        kAudioUnitScope_Output, 0, vol, 0);
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TSoundOutputDevice::supportsVolume() { return true; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TSoundOutputDevice::isPlaying() const {
Shinya Kitaoka 120a6e
  // TThread::ScopedLock sl(MutexOut);
Shinya Kitaoka 120a6e
  return m_imp->m_isPlaying;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TSoundOutputDevice::isLooping() {
Shinya Kitaoka 120a6e
  // TThread::ScopedLock sl(MutexOut);
Shinya Kitaoka 120a6e
  return m_imp->m_looped;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TSoundOutputDevice::setLooping(bool loop) {
Shinya Kitaoka 120a6e
  // TThread::ScopedLock sl(MutexOut);
Shinya Kitaoka 120a6e
  m_imp->m_looped = loop;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TSoundTrackFormat TSoundOutputDevice::getPreferredFormat(TUINT32 sampleRate,
Shinya Kitaoka 120a6e
                                                         int channelCount,
Shinya Kitaoka 120a6e
                                                         int bitPerSample) {
Shinya Kitaoka 120a6e
  TSoundTrackFormat fmt(sampleRate, bitPerSample, channelCount, true);
Shinya Kitaoka 120a6e
  return fmt;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TSoundTrackFormat TSoundOutputDevice::getPreferredFormat(
Shinya Kitaoka 120a6e
    const TSoundTrackFormat &format) {
Shinya Kitaoka 120a6e
  // try {
Shinya Kitaoka 120a6e
  return getPreferredFormat(format.m_sampleRate, format.m_channelCount,
Shinya Kitaoka 120a6e
                            format.m_bitPerSample);
Shinya Kitaoka 120a6e
  /*}
Shinya Kitaoka 120a6e
catch (TSoundDeviceException &e) {
Shinya Kitaoka 120a6e
throw TSoundDeviceException( e.getType(), e.getMessage());
Shinya Kitaoka 120a6e
}*/
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
//                REGISTRAZIONE
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class TSoundInputDeviceImp {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  // ALport m_port;
Shinya Kitaoka 120a6e
  bool m_stopped;
Shinya Kitaoka 120a6e
  bool m_isRecording;
Shinya Kitaoka 120a6e
  bool m_oneShotRecording;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  long m_recordedSampleCount;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TSoundTrackFormat m_currentFormat;
Shinya Kitaoka 120a6e
  TSoundTrackP m_st;
Shinya Kitaoka 120a6e
  std::set<int> m_supportedRate;</int>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TThread::Executor m_executor;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TSoundInputDeviceImp()
Shinya Kitaoka 120a6e
      : m_stopped(false)
Shinya Kitaoka 120a6e
      , m_isRecording(false)
Shinya Kitaoka 120a6e
      //   , m_port(NULL)
Shinya Kitaoka 120a6e
      , m_oneShotRecording(false)
Shinya Kitaoka 120a6e
      , m_recordedSampleCount(0)
Shinya Kitaoka 120a6e
      , m_st(0)
Shinya Kitaoka 120a6e
      , m_supportedRate(){};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ~TSoundInputDeviceImp(){};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bool doOpenDevice(const TSoundTrackFormat &format,
Shinya Kitaoka 120a6e
                    TSoundInputDevice::Source devType);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TSoundInputDeviceImp::doOpenDevice(const TSoundTrackFormat &format,
Shinya Kitaoka 120a6e
                                        TSoundInputDevice::Source devType) {
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class RecordTask : public TThread::Runnable {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  TSoundInputDeviceImp *m_devImp;
Shinya Kitaoka 120a6e
  int m_ByteToSample;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  RecordTask(TSoundInputDeviceImp *devImp, int numByte)
Shinya Kitaoka 120a6e
      : TThread::Runnable(), m_devImp(devImp), m_ByteToSample(numByte){};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ~RecordTask(){};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void run();
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void RecordTask::run() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TSoundInputDevice::TSoundInputDevice() : m_imp(new TSoundInputDeviceImp) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TSoundInputDevice::~TSoundInputDevice() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TSoundInputDevice::installed() {
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
  if (alQueryValues(AL_SYSTEM, AL_DEFAULT_INPUT, 0, 0, 0, 0) <=0)
Shinya Kitaoka 120a6e
return false;
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TSoundInputDevice::record(const TSoundTrackFormat &format,
Shinya Kitaoka 120a6e
                               TSoundInputDevice::Source type) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TSoundInputDevice::record(const TSoundTrackP &st,
Shinya Kitaoka 120a6e
                               TSoundInputDevice::Source type) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TSoundTrackP TSoundInputDevice::stop() {
Shinya Kitaoka 120a6e
  TSoundTrackP st;
Shinya Kitaoka 120a6e
  return st;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
double TSoundInputDevice::getVolume() { return 0.0; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TSoundInputDevice::setVolume(double volume) { return true; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TSoundInputDevice::supportsVolume() { return true; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TSoundTrackFormat TSoundInputDevice::getPreferredFormat(TUINT32 sampleRate,
Shinya Kitaoka 120a6e
                                                        int channelCount,
Shinya Kitaoka 120a6e
                                                        int bitPerSample) {
Shinya Kitaoka 120a6e
  TSoundTrackFormat fmt;
Shinya Kitaoka 120a6e
  return fmt;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TSoundTrackFormat TSoundInputDevice::getPreferredFormat(
Shinya Kitaoka 120a6e
    const TSoundTrackFormat &format) {
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
try {
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
  return getPreferredFormat(format.m_sampleRate, format.m_channelCount,
Shinya Kitaoka 120a6e
                            format.m_bitPerSample);
Shinya Kitaoka 120a6e
  /*}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
catch (TSoundDeviceException &e) {
Shinya Kitaoka 120a6e
throw TSoundDeviceException( e.getType(), e.getMessage());
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
*/
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TSoundInputDevice::isRecording() { return m_imp->m_isRecording; }