Example #1
0
/* ////////////////////////// PUBLIC STATIC ///////////////////////////////// */
UtlString MpidWinMM::getDefaultDeviceName()
{
   UtlString devName = "";

   // Get windows default input device name
   unsigned nDevs = waveInGetNumDevs();
   if (nDevs == 0)
   {
      OsSysLog::add(FAC_AUDIO, PRI_ERR, 
                    "MpidWinMM::getDefaultDeviceName: "
                    "No input audio devices present!");
   }
   assert(nDevs != 0);

   MMRESULT wavResult = MMSYSERR_NOERROR;
   WAVEINCAPS devCaps;
   int defaultWinDeviceId = 0;
   wavResult = 
      waveInGetDevCaps(defaultWinDeviceId, &devCaps, sizeof(devCaps));
   if (wavResult != MMSYSERR_NOERROR)
   {
      OsSysLog::add(FAC_AUDIO, PRI_ERR, 
                    "MpodWinMM::getDefaultDeviceName: "
                    "Couldn't get default input device capabilities!");
      showWaveError("WINDOWS_DEFAULT_DEVICE_HACK",
                    wavResult, -1, __LINE__);
   }
   else
   {
      devName = devCaps.szPname;
   }
   assert(wavResult == MMSYSERR_NOERROR);
   return devName;
}
Example #2
0
// This function will attempt to open a user specified audio device.
// If it fails, we will try to open any audio device that meets our requested format
// If we still fail, we will return 0, and display a message.
// TODO: Seems we have a problem when no audio device can be found. No calls can be made.
//       I recommend we bubble this up to java and display a message.
static int openAudioOut(int desiredDeviceId, HWAVEOUT *pAudioOutH,int nChannels, int nSamplesPerSec, int nBitsPerSample)
{
   WAVEFORMATEX fmt;
   MMRESULT     res;

   *pAudioOutH = NULL;

   fmt.wFormatTag      = WAVE_FORMAT_PCM;
   fmt.nChannels       = nChannels;
   fmt.nSamplesPerSec  = nSamplesPerSec;
   fmt.nAvgBytesPerSec = (nChannels * nSamplesPerSec * nBitsPerSample) / 8;
   fmt.nBlockAlign     = (nChannels * nBitsPerSample) / 8;
   fmt.wBitsPerSample  = nBitsPerSample;
   fmt.cbSize          = 0;

   res = waveOutOpen(
      pAudioOutH,             // handle (will be filled in)
      desiredDeviceId,        // select the device specified by user
      &fmt,                   // format
      (DWORD) speakerCallbackProc,// callback entry
      GetCurrentThreadId(),   // instance data
      CALLBACK_FUNCTION);     // callback function specified

   //if we fail to open the audio device above, then we 
   //will try to open any device that will hande the requested format
   if (res != MMSYSERR_NOERROR)
      res = waveOutOpen(
         pAudioOutH,             // handle (will be filled in)
         WAVE_MAPPER,            // select any device able to handle this format
         &fmt,                   // format
         (DWORD) speakerCallbackProc,// callback entry
         GetCurrentThreadId(),   // instance data
         CALLBACK_FUNCTION);     // callback function specified
   
   if (res != MMSYSERR_NOERROR)
   {
      //hmm, couldn't open any audio device... things don't look good at this point
      showWaveError("waveOutOpen", res, -1, __LINE__);
      waveOutClose(*pAudioOutH);
      *pAudioOutH = NULL;
      return 0;
   }
   else
   {
      return 1;
   }
}
Example #3
0
void MpidWinMM::processAudioInput(HWAVEIN hwi,
                                  UINT uMsg,
                                  void* dwParam1)
{
    if (!mIsOpen)
    {
        assert(uMsg == WIM_OPEN);
        if (uMsg == WIM_OPEN)
        {
//            printf("received WIM_OPEN\n"); fflush(stdout);
            mIsOpen = TRUE;
        }
    }
    if (uMsg == WIM_DATA)
    {
//        printf("received WIM_DATA\n"); fflush(stdout);
        assert(mIsOpen);
        WAVEHDR* pWaveHdr = (WAVEHDR*)dwParam1;
        assert(pWaveHdr->dwBufferLength 
               == (mSamplesPerFrame*sizeof(MpAudioSample)));
        assert(pWaveHdr->lpData != NULL);

        // Only process if we're enabled..
        if(mIsEnabled)
        {
#ifdef TEST_PRINT
            OsSysLog::add(FAC_MP, PRI_DEBUG,
                "MpidWinMM::processAudioInput got frame device: %d (%s)", 
                getDeviceId(), getDeviceName().data());
#endif
           mpInputDeviceManager->pushFrame(mDeviceId,
                                           mSamplesPerFrame,
                                           (MpAudioSample*)pWaveHdr->lpData,
                                           mCurrentFrameTime);
           // Ok, we have received and pushed a frame to the manager,
           // Now we advance the frame time.
           mCurrentFrameTime += (mSamplesPerFrame*1000)/mSamplesPerSec;
        }
        else
        {
            OsSysLog::add(FAC_MP, PRI_DEBUG,
                "MpidWinMM::processAudioInput input device: %d (%s) disabled", 
                getDeviceId(), getDeviceName().data());
        }

        if(mIsEnabled)
        {
           // Put the wave header back in the pool..
           MMRESULT res = MMSYSERR_NOERROR;

           res = waveInAddBuffer(mDevHandle, pWaveHdr, sizeof(WAVEHDR));
           if (res != MMSYSERR_NOERROR)
           {
              showWaveError("waveInAddBuffer", res, -1, __LINE__);
              mnAddBufferFailures++;
              if(mnAddBufferFailures >= mNumInBuffers)
              {
                 waveInClose(mDevHandle);
                 mDevHandle = NULL;
                 mWinMMDeviceId = -1;
              }
           }
        }
    }
    else if (uMsg == WIM_CLOSE)
    {
//        printf("received WIM_CLOSE\n"); fflush(stdout);
        mIsOpen = FALSE;
    }
}
Example #4
0
OsStatus MpidWinMM::disableDevice()
{
    OsStatus status = OS_SUCCESS;
    MMRESULT   res;
    
    if (!isDeviceValid() || !isEnabled())
    {
        return OS_FAILED;
    }

    // Indicate we are no longer enabled -- Do this first,
    // since we'll be partially disabled from here on out.
    // It is very important that this happen *before* waveInReset,
    // as the callback will continue to add and process buffers
    // while waveInReset is called causing a deadlock.
    mIsEnabled = FALSE;

    // Cleanup
    if (mDevHandle == NULL)
    {
        return OS_INVALID_STATE;
    }

    // Reset performs a stop, resets the buffers, and marks them
    // for being sent to the callback.
    // The remaining data in the windows buffers *IS* sent to the callback,
    // So be sure to watch for it and drop it on the floor.
    res = waveInReset(mDevHandle);
    if (res != MMSYSERR_NOERROR)
    {
        showWaveError("waveInReset", res, -1, __LINE__);
    } 

    // Must unprepare the headers after a reset, but before the device is closed
    // (if this is done after waveInClose, mDevHandle will be invalid and 
    // MMSYSERR_INVALHANDLE will be returned.
    unsigned i;
    for (i=0; i < mNumInBuffers; i++) 
    {
        res = waveInUnprepareHeader(mDevHandle, &mpWaveHeaders[i], sizeof(WAVEHDR));
        if (res != MMSYSERR_NOERROR)
        {
            showWaveError("waveInUnprepareHeader", res, i, __LINE__);
        }
    }

    res = waveInClose(mDevHandle);
    if (res != MMSYSERR_NOERROR)
    {
        showWaveError("waveInClose", res, -1, __LINE__);
    }

    // Delete the buffers that were allocated in enableDevice()
    for (i = 0; i < mNumInBuffers; i++)
    {
        delete[] mpWaveBuffers[i];
        mpWaveBuffers[i] = NULL;
    }

    // set the device handle to NULL, since it no longer is valid.
    mDevHandle = NULL;

    // Clear out all the wave header information.
    mSamplesPerFrame = 0;
    mSamplesPerSec = 0;
    mCurrentFrameTime = 0;

    return status;
}
Example #5
0
OsStatus MpidWinMM::enableDevice(unsigned samplesPerFrame, 
                                 unsigned samplesPerSec, 
                                 MpFrameTime currentFrameTime)
{
    OsStatus status = OS_SUCCESS;

    // reset the number of addBuffer failures, as we're starting fresh now.
    mnAddBufferFailures = 0;

    // If the device is not valid, let the user know it's bad.
    if (!isDeviceValid())
    {
        return OS_INVALID_STATE;  // perhaps new OsState of OS_RESOURCE_INVALID?
    }

    if (isEnabled())
    {
        return OS_FAILED;
    }

    // Set some wave header stat information.
    mSamplesPerFrame = samplesPerFrame;
    mSamplesPerSec = samplesPerSec;
    mCurrentFrameTime = currentFrameTime;

    // Do stuff to enable device.
    int nChannels = 1;
    WAVEFORMATEX wavFormat;
    wavFormat.wFormatTag = WAVE_FORMAT_PCM;
    wavFormat.nChannels = nChannels;
    wavFormat.nSamplesPerSec = mSamplesPerSec;
    wavFormat.nAvgBytesPerSec = 
        nChannels * mSamplesPerSec * sizeof(MpAudioSample);
    wavFormat.nBlockAlign = nChannels * sizeof(MpAudioSample);
    wavFormat.wBitsPerSample = sizeof(MpAudioSample) * 8;
    wavFormat.cbSize = 0;

    // Tell windows to open the input audio device.  This doesn't
    // tell it to send the data to our callback yet, just to get it ready
    // to do so..
    MMRESULT res = waveInOpen(&mDevHandle, mWinMMDeviceId,
                              &wavFormat,
                              (CBTYPE)waveInCallbackStatic,
                              (CBTYPE)this, 
                              CALLBACK_FUNCTION);
    if (res != MMSYSERR_NOERROR)
    {
        // If waveInOpen failed, print out the error info,
        // invalidate the handle, and the device driver itself,
        status = OS_FAILED;
        showWaveError("MpidWinMM::enableDevice", res, -1, __LINE__);
        waveInClose(mDevHandle);
        mDevHandle = NULL; // Open didn't work, reset device handle to NULL
        mWinMMDeviceId = -1; // Make device invalid.

        // and return OS_FAILED.
        return status;
    }


    // Allocate the buffers we are going to use to receive audio data from
    // the windows audio input callback.
    // Calculate the buffer length we're going to use. 
    // number of samples per frame * sample size in bytes
    mWaveBufSize = mSamplesPerFrame * sizeof(MpAudioSample); 
    unsigned i;
    for (i = 0; i < mNumInBuffers; i++)
    {
        mpWaveBuffers[i] = new char[mWaveBufSize];
    }


    // Setup the buffers so windows can stuff them full of audio
    // when it becomes available from this audio input device.
    WAVEHDR* pWaveHdr = NULL;
    for (i=0; i < mNumInBuffers; i++) 
    {
        pWaveHdr = initWaveHeader(i);

        res = waveInPrepareHeader(mDevHandle, pWaveHdr, sizeof(WAVEHDR));
        if (res != MMSYSERR_NOERROR)
        {
            showWaveError("waveInPrepareHeader", res, i, __LINE__);
            waveInClose(mDevHandle);
            mDevHandle = NULL;
            mWinMMDeviceId = -1;

            // and return OS_FAILED.
            return status;
        }
        res = waveInAddBuffer(mDevHandle, pWaveHdr, sizeof(WAVEHDR));
        if (res != MMSYSERR_NOERROR)
        {
            showWaveError("waveInAddBuffer", res, i, __LINE__);
            waveInClose(mDevHandle);
            mDevHandle = NULL;
            mWinMMDeviceId = -1;

            // and return OS_FAILED.
            return status;
        }
    }

    // Tell windows to start sending audio data to the callback.
    res = waveInStart(mDevHandle);
    if (res != MMSYSERR_NOERROR)
    {
        // If waveInStart failed, print out the error info,
        // invalidate the handle and the device driver itself,
        status = OS_FAILED;
        showWaveError("waveInStart", res, -1, __LINE__);
        waveInClose(mDevHandle);
        mDevHandle = NULL;
        mWinMMDeviceId = -1;

        // and return OS_FAILED.
        return status;
    }

    // If enableDevice failed, return indicating failure.
    if (status == OS_SUCCESS)
    {
        mIsEnabled = TRUE;
    }

    return status;
}
Example #6
0
unsigned int __stdcall SpkrThread(LPVOID Unused)
{
    int      i;
    DWORD    bufLen = ((N_SAMPLES * BITS_PER_SAMPLE) / 8);
    WAVEHDR* pWH;
    MMRESULT ret;
    int      played;
    OsMsg *pMsg = NULL;
    OsIntPtrMsg *pSpeakerMsg = NULL;
    BOOL     bGotMsg ;
    int      n;
    bool     bDone ;
    static bool sLastRingerEnabled = false;
    OsStatus res;
    static bool bRunning = false ;
    HWAVEOUT hOut = NULL;
    UINT    timerId=0;

    // Verify that only 1 instance of the MicThread is running
    if (bRunning) 
    {
       ResumeThread(hMicThread);
       return 1 ;
    }
    else
    {
       bRunning = true ;
    }
    ResumeThread(hMicThread);


#ifdef OHISTORY /* [ */
    WAVEHDR* lastWH[OHISTORY];
    int      lastInd[OHISTORY];
    int      last = 0;

    for (i=0;i<OHISTORY;i++) 
    {
        lastWH[i] = 0;
        lastInd[i] = 0;
    }

    memset(histOut, 0xff, sizeof(histOut));
    lastOut = 0;
#endif /* OHISTORY ] */
    
    // Initialize headers
    for (i=0; i<N_OUT_BUFFERS; i++) 
    {
        hOutHdr[i] = hOutBuf[i] = NULL;
        pOutHdr[i] = NULL;
    }
    
    if (openSpeakerDevices(pWH, hOut))
    {
        // NOT using a sound card
        // Set up a 10ms timer to call back to this routine
        timerId = timeSetEvent(10, 0, TimerCallbackProc, GetCurrentThreadId(), TIME_PERIODIC);
    }

    played = 0;   
    bDone = false ;
    while (!bDone)
    {
       bGotMsg = (gSpeakerStatusQueue->receive(pMsg) == OS_SUCCESS);
              
        // when switching devices, ringer to in-call we need to make 
        // sure any outstanding buffers are flushed
        if (sLastRingerEnabled != DmaTask::isRingerEnabled())
        {
            if (audioOutH)
            {
                ret = waveOutReset(audioOutH);
            }
            if (audioOutCallH)
            {
                ret = waveOutReset(audioOutCallH);
            }

            if (ret != MMSYSERR_NOERROR)
            {
                showWaveError("waveOutReset", ret, -1, __LINE__);
            }
            else
            {
                waitForDeviceResetCompletion();
            }
        }

        if (bGotMsg && pMsg) 
        {
           pSpeakerMsg = (OsIntPtrMsg*)pMsg;
           intptr_t msgType = pSpeakerMsg->getData1();
           intptr_t data2 = pSpeakerMsg->getData2();
           pSpeakerMsg->releaseMsg();
           pSpeakerMsg = NULL;
           pMsg = NULL;

            switch (msgType) 
            {
            case WM_ALT_HEARTBEAT:
                OsSysLog::add(FAC_MP, PRI_DEBUG,
                    "SpeakerThreadWnt invoking MpMediaTask::signalFrameStart from timer message");
                res = MpMediaTask::signalFrameStart();
                switch (res) 
                {
                   case OS_SUCCESS:
                        frameCount++;
                        break;
#ifdef DEBUG_WINDOZE /* [ */
                   case OS_LIMIT_REACHED:
                      // Should bump missed frame statistic
                      osPrintf(" Frame %d: OS_LIMIT_REACHED\n", frameCount);
                      break;
                   case OS_WAIT_TIMEOUT:
                      // Should bump missed frame statistic
                      osPrintf(" Frame %d: OS_WAIT_TIMEOUT\n", frameCount);
                      break;
                   case OS_ALREADY_SIGNALED:
                      // Should bump missed frame statistic
                      osPrintf(" Frame %d: OS_ALREADY_SIGNALED\n", frameCount);
                      break;
                   default:
                      osPrintf("Frame %d, signalFrameStart() returned %d\n",
                               frameCount, res);
                      break;
#else /* DEBUG_WINDOZE ] [ */
                   case OS_LIMIT_REACHED:
                   case OS_WAIT_TIMEOUT:
                   case OS_ALREADY_SIGNALED:
                   default:
                      // Should bump missed frame statistic
                      break;
#endif /* DEBUG_WINDOZE ] */
                }
                // Check for a changed speaker device
                if (DmaTask::isOutputDeviceChanged())
                {                    
                    DmaTask::clearOutputDeviceChanged() ;
                    closeSpeakerDevices() ;
                    if (audioOutH)
                    {
                        ret = waveOutReset(audioOutH);
                    }
                    if (audioOutCallH)
                    {
                        ret = waveOutReset(audioOutCallH);
                    }

                    if (ret != MMSYSERR_NOERROR)
                    {
                        showWaveError("waveOutReset", ret, -1, __LINE__);
                    }
                    else
                    {
                        waitForDeviceResetCompletion();
                    }

                    // Kill the hearbeat timer if it exists
                    if (timerId>0)
                        timeKillEvent(timerId);
                    if (openSpeakerDevices(pWH, hOut))
                    {
                        // Open failed - so start the heartbeat timer
                        timerId = timeSetEvent(10, 0, TimerCallbackProc, GetCurrentThreadId(), TIME_PERIODIC);                    
                    }
                    continue ;                    
                }
                break ;
            case WOM_DONE:
                pWH = (WAVEHDR *) data2;
                n = (pWH->dwUser) & USER_BUFFER_MASK;
#ifdef OHISTORY /* [ */
                lastWH[last] = pWH;
                lastInd[last] = n;
                last = (last + 1) % OHISTORY;

                if (N_OUT_BUFFERS == played) {
                    osPrintf("after first %d buffers:", played + 1);
                    osPrintf("\nCall Backs:");
                    for (i=0; i<OHISTORY; i++) {
                        osPrintf("%c%3d", (0 == (i % 20)) ? '\n' : ' ',
                        histOut[i]);
                    }
                    osPrintf("\n\nMessages:");
                    for (i=0; i<OHISTORY; i++) {
                        osPrintf("%c%3d", (0 == (i % 20)) ? '\n' : ' ',
                        lastInd[i]);
                    }
                    osPrintf("\n");
                }
#endif /* OHISTORY ] */
                
                if (DmaTask::isOutputDeviceChanged())
                {                    
                    DmaTask::clearOutputDeviceChanged() ;
                    closeSpeakerDevices() ;
                    if (openSpeakerDevices(pWH, hOut))
                    {
                        if (timerId>0)
                            timeKillEvent(timerId);
                        timerId = timeSetEvent(10, 0, TimerCallbackProc, GetCurrentThreadId(), TIME_PERIODIC);                    
                    }
                    continue ;                    
                }

                hOut = selectSpeakerDevice() ;
                if (hOut)
                {
                    ret = waveOutUnprepareHeader(hOut, pWH, sizeof(WAVEHDR));
                    if (ret != MMSYSERR_NOERROR)
                    {
                           showWaveError("waveOutUnprepareHeader", ret, played, __LINE__);
                    }
                    outPostUnprep(n, false);

                    pWH = outPrePrep(n, bufLen);

                    ret = waveOutPrepareHeader(hOut, pWH, sizeof(WAVEHDR));
                    if (ret != MMSYSERR_NOERROR)
                    {
                           showWaveError("waveOutPrepareHeader", ret, played, __LINE__);
                    }
                    ret = waveOutWrite(hOut, pWH, sizeof(WAVEHDR));
                    if (ret != MMSYSERR_NOERROR)
                    {
                           showWaveError("waveOutWrite", ret, played, __LINE__);
                    }
                    played++;
                }

                OsSysLog::add(FAC_MP, PRI_DEBUG,
                    "SpeakerThreadWnt invoking MpMediaTask::signalFrameStart from WOM_DONE message");
                res = MpMediaTask::signalFrameStart();

                switch (res) 
                {
#ifdef DEBUG_WINDOZE /* [ */
                case OS_SUCCESS:
                    frameCount++;
                    osPrintf(" Frame %d: OS_SUCCESSFUL\n", frameCount);
                    break;
                case OS_LIMIT_REACHED:
                    // Should bump missed frame statistic
                    osPrintf(" Frame %d: OS_LIMIT_REACHED\n", frameCount);
                   break;
                case OS_WAIT_TIMEOUT:
                    // Should bump missed frame statistic
                    osPrintf(" Frame %d: OS_WAIT_TIMEOUT\n", frameCount);
                    break;
                case OS_ALREADY_SIGNALED:
                    // Should bump missed frame statistic
                    osPrintf(" Frame %d: OS_ALREADY_SIGNALED\n", frameCount);
                    break;
                default:
                    osPrintf("Frame %d, signalFrameStart() returned %d\n",
                            frameCount, res);
                    break;
#else /* DEBUG_WINDOZE ] [ */
                case OS_SUCCESS:
                    frameCount++;
                    break;
                case OS_LIMIT_REACHED:
                case OS_WAIT_TIMEOUT:
                case OS_ALREADY_SIGNALED:
                default:
                    // Should bump missed frame statistic
                    break;
#endif /* DEBUG_WINDOZE ] */
                }
                break;
            case WOM_CLOSE:
                // Audio device was closed on us (doesn't happen as far as I
                // know)
                bDone = true ;
                break;
            default:                
                break;
            }
        } 
        else 
        {
            // Sky is falling, kick out so that we don't spin a high priority
            // thread.
            bDone = true ;
        }
      
        // record our last ringer state
        sLastRingerEnabled = DmaTask::isRingerEnabled();
    }

    // Stop heartbeat timer if it exist
    if (timerId>0)
        timeKillEvent(timerId);

    closeSpeakerDevices() ;

    bRunning = false ;

    return 0;
}
Example #7
0
void closeSpeakerDevices()
{
    MMRESULT ret;
    int i ;

    // Clean up ringer audio
    if (audioOutH)
    {
        ret = waveOutReset(audioOutH);
        if (ret != MMSYSERR_NOERROR)
        {
            showWaveError("waveOutReset", ret, -1, __LINE__);
        }
        else
        {
            waitForDeviceResetCompletion();
        }

        for (i=0; i<N_OUT_BUFFERS; i++) 
        {
            if (NULL != hOutHdr[i]) 
            {
                ret = waveOutUnprepareHeader(audioOutH, pOutHdr[i], sizeof(WAVEHDR));
                if (ret != MMSYSERR_NOERROR)
                {
                    showWaveError("waveOutUnprepareHeader", ret, i, __LINE__);
                }
                outPostUnprep(i, TRUE);
            }
        }
        
        ret = waveOutClose(audioOutH);
        if (ret != MMSYSERR_NOERROR)
        {
            showWaveError("waveOutClose", ret, -1, __LINE__);
        }
        audioOutH = NULL;

        waitForSpeakerStatusMessage(WOM_CLOSE);
    }

    // Clean up call audio
    if (audioOutCallH)
    {
        ret = waveOutReset(audioOutCallH);
        if (ret != MMSYSERR_NOERROR)
        {
            showWaveError("waveOutReset", ret, -1, __LINE__);
        }
        else
        {
            waitForDeviceResetCompletion();
        }

        for (i=0; i<N_OUT_BUFFERS; i++) 
        {
            if (NULL != hOutHdr[i]) 
            {
                ret = waveOutUnprepareHeader(audioOutCallH, pOutHdr[i], sizeof(WAVEHDR));
                if (ret != MMSYSERR_NOERROR)
                {
                    showWaveError("waveOutUnprepareHeader", ret, i, __LINE__);
                }
                outPostUnprep(i, true);
            }
        }

        ret = waveOutClose(audioOutCallH);
        if (ret != MMSYSERR_NOERROR)
        {
             showWaveError("waveOutClose", ret, -1, __LINE__);
        }
        audioOutCallH = NULL;

        waitForSpeakerStatusMessage(WOM_CLOSE);
    }
}
Example #8
0
static int openSpeakerDevices(WAVEHDR*& pWH, HWAVEOUT& hOut)
{
    DWORD    bufLen = ((N_SAMPLES * BITS_PER_SAMPLE) / 8);
    int i ;
    MMRESULT ret;

    // set the different device ids
    gRingDeviceId = WAVE_MAPPER;
    gCallDeviceId = WAVE_MAPPER;


    // If either the ringer or call device is set to NONE, don't engage any audio devices
    if ((strcasecmp(DmaTask::getRingDevice(), "NONE") == 0) ||
        (strcasecmp(DmaTask::getCallDevice(), "NONE") == 0))
    {
        ResumeThread(hMicThread);
        return 1;
    }

    /*
     * Select in-call / ringer devices
     */
    int ii;
    WAVEOUTCAPS devcaps;
    int numberOfDevicesOnSystem = waveOutGetNumDevs();
    for(ii=0; ii<numberOfDevicesOnSystem; ii++)
    {
        waveOutGetDevCaps(ii,&devcaps,sizeof(WAVEOUTCAPS));
        if (strcmp(devcaps.szPname, DmaTask::getRingDevice())==0) 
        {
            gRingDeviceId = ii;
            OsSysLog::add(FAC_MP, PRI_DEBUG,
                "SpkrThread: Selected ring device: %s\n",devcaps.szPname);
        }

        if (strcmp(devcaps.szPname, DmaTask::getCallDevice())==0) 
        {
            gCallDeviceId = ii;
            OsSysLog::add(FAC_MP, PRI_DEBUG,
                "SpkrThread: Selected call device: %s\n",devcaps.szPname);
        }
    }

    /*
     * Open ringer device
     */ 
    if (!openAudioOut(gRingDeviceId, &audioOutH, 1, SAMPLES_PER_SEC, BITS_PER_SAMPLE))
    {
        OsSysLog::add(FAC_MP, PRI_DEBUG,
            "SpkrThread: Failed to open ring audio output channel\n\n");
        ResumeThread(hMicThread);
        return 1;
    }

    waitForSpeakerStatusMessage(WOM_OPEN);

    /*
     * Open in-call device
     */
    if (!openAudioOut(gCallDeviceId,&audioOutCallH, 1, SAMPLES_PER_SEC, BITS_PER_SAMPLE))
    {
        OsSysLog::add(FAC_MP, PRI_DEBUG,
            "SpkrThread: Failed to open call audio output channel\n\n");
        ResumeThread(hMicThread);
        return 1;
    }

    waitForSpeakerStatusMessage(WOM_OPEN);

    // Pre load some data    
    for (i=0; i<smSpkrQPreload; i++)
    {
        pWH = outPrePrep(i, bufLen);

        hOut = selectSpeakerDevice() ;
        if (hOut)
        {
            ret = waveOutPrepareHeader(hOut, pWH, sizeof(WAVEHDR));
            if (ret != MMSYSERR_NOERROR)
            {
                showWaveError("waveOutPrepareHeader", ret, i, __LINE__);
            }
            ret = waveOutWrite(hOut, pWH, sizeof(WAVEHDR));
            if (ret != MMSYSERR_NOERROR)
            {
                   showWaveError("waveOutWrite", ret, i, __LINE__);
            }
        }      
    }

    return 0 ;
}
Example #9
0
void closeSpeakerDevices()
{
    MMRESULT ret;
    int i ;
    MSG tMsg;
    BOOL bSuccess ;    


    // Clean up ringer audio
    if (audioOutH)
    {
        ret = waveOutReset(audioOutH);
        Sleep(100) ;
        if (ret != MMSYSERR_NOERROR)
        {
            showWaveError("waveOutReset", ret, -1, __LINE__);
        }

        for (i=0; i<N_OUT_BUFFERS; i++) 
        {
            if (NULL != hOutHdr[i]) 
            {
                ret = waveOutUnprepareHeader(audioOutH, pOutHdr[i], sizeof(WAVEHDR));
                if (ret != MMSYSERR_NOERROR)
                {
                    showWaveError("waveOutUnprepareHeader", ret, i, __LINE__);
                }
                outPostUnprep(i, TRUE);
            }
        }
        
        ret = waveOutClose(audioOutH);
        if (ret != MMSYSERR_NOERROR)
        {
            showWaveError("waveOutClose", ret, -1, __LINE__);
        }
        audioOutH = NULL;

        do 
        {
            bSuccess = GetMessage(&tMsg, NULL, 0, 0) ;
        } while (bSuccess && (tMsg.message != WOM_CLOSE)) ;
    }

    // Clean up call audio
    if (audioOutCallH)
    {
        ret = waveOutReset(audioOutCallH);
        Sleep(100) ;
        if (ret != MMSYSERR_NOERROR)
        {
            showWaveError("waveOutReset", ret, -1, __LINE__);
        }

        for (i=0; i<N_OUT_BUFFERS; i++) 
        {
            if (NULL != hOutHdr[i]) 
            {
                ret = waveOutUnprepareHeader(audioOutCallH, pOutHdr[i], sizeof(WAVEHDR));
                if (ret != MMSYSERR_NOERROR)
                {
                    showWaveError("waveOutUnprepareHeader", ret, i, __LINE__);
                }
                outPostUnprep(i, true);
            }
        }

        ret = waveOutClose(audioOutCallH);
        if (ret != MMSYSERR_NOERROR)
        {
             showWaveError("waveOutClose", ret, -1, __LINE__);
        }
        audioOutCallH = NULL;

        do 
        {
            bSuccess = GetMessage(&tMsg, NULL, 0, 0) ;
        } while (bSuccess && (tMsg.message != WOM_CLOSE)) ;
    }
}
Example #10
0
unsigned int __stdcall SpkrThread(LPVOID Unused)
{
    int      i;
    DWORD    bufLen = ((N_SAMPLES * BITS_PER_SAMPLE) / 8);
    WAVEHDR* pWH;
    MMRESULT ret;
    int      played;
    MSG      tMsg;
    BOOL     bGotMsg ;
    int      n;
    bool     bDone ;
    static bool sLastRingerEnabled = false;
    OsStatus res;
    static bool bRunning = false ;
    HWAVEOUT hOut = NULL;

    // Verify that only 1 instance of the MicThread is running
    if (bRunning) 
    {
       ResumeThread(hMicThread);
       return 1 ;
    }
    else
    {
       bRunning = true ;
    }
    ResumeThread(hMicThread);


#ifdef OHISTORY /* [ */
    WAVEHDR* lastWH[OHISTORY];
    int      lastInd[OHISTORY];
    int      last = 0;

    for (i=0;i<OHISTORY;i++) 
    {
        lastWH[i] = 0;
        lastInd[i] = 0;
    }

    memset(histOut, 0xff, sizeof(histOut));
    lastOut = 0;
#endif /* OHISTORY ] */
    
    // Initialize headers
    for (i=0; i<N_OUT_BUFFERS; i++) 
    {
        hOutHdr[i] = hOutBuf[i] = NULL;
        pOutHdr[i] = NULL;
    }
    
    if (openSpeakerDevices(pWH, hOut))
    {
        // NOT using a sound card
        // Set up a 10ms timer to call back to this routine
        timeSetEvent(10, 0, TimerCallbackProc, GetCurrentThreadId(), TIME_PERIODIC);
    }

    played = 0;   
    bDone = false ;
    while (!bDone)
    {
        bGotMsg = GetMessage(&tMsg, NULL, 0, 0);
              
        // when switching devices, ringer to in-call we need to make 
        // sure any outstanding buffers are flushed
        if (sLastRingerEnabled != DmaTask::isRingerEnabled())
        {
            if (audioOutH)
            {
                waveOutReset(audioOutH);
            }
            if (audioOutCallH)
            {
                waveOutReset(audioOutCallH);
            }
        }

        if (bGotMsg) 
        {
            switch (tMsg.message) 
            {
            case WM_ALT_HEARTBEAT:
                res = MpMediaTask::signalFrameStart();
                switch (res) 
                {
                    case OS_SUCCESS:
                        frameCount++;
                        break;
                    case OS_LIMIT_REACHED:
                    case OS_WAIT_TIMEOUT:
                    case OS_ALREADY_SIGNALED:
                    default:
                        // Should bump missed frame statistic
                        break;
                }
                break ;
            case WOM_DONE:
                pWH = (WAVEHDR *) tMsg.wParam;
                n = (pWH->dwUser) & USER_BUFFER_MASK;
#ifdef OHISTORY /* [ */
                lastWH[last] = pWH;
                lastInd[last] = n;
                last = (last + 1) % OHISTORY;

                if (N_OUT_BUFFERS == played) {
                    osPrintf("after first %d buffers:", played + 1);
                    osPrintf("\nCall Backs:");
                    for (i=0; i<OHISTORY; i++) {
                        osPrintf("%c%3d", (0 == (i % 20)) ? '\n' : ' ',
                        histOut[i]);
                    }
                    osPrintf("\n\nMessages:");
                    for (i=0; i<OHISTORY; i++) {
                        osPrintf("%c%3d", (0 == (i % 20)) ? '\n' : ' ',
                        lastInd[i]);
                    }
                    osPrintf("\n");
                }
#endif /* OHISTORY ] */
                
                if (DmaTask::isOutputDeviceChanged())
                {                    
                    DmaTask::clearOutputDeviceChanged() ;
                    closeSpeakerDevices() ;
                    if (openSpeakerDevices(pWH, hOut))
                    {
                        timeSetEvent(10, 0, TimerCallbackProc, GetCurrentThreadId(), TIME_PERIODIC);                    
                    }
                    continue ;                    
                }

                hOut = selectSpeakerDevice() ;
                if (hOut)
                {
			        ret = waveOutUnprepareHeader(hOut, pWH, sizeof(WAVEHDR));
                    if (ret != MMSYSERR_NOERROR)
                    {
   				        showWaveError("waveOutUnprepareHeader", ret, played, __LINE__);
                    }
				    outPostUnprep(n, false);

				    pWH = outPrePrep(n, bufLen);

				    ret = waveOutPrepareHeader(hOut, pWH, sizeof(WAVEHDR));
                    if (ret != MMSYSERR_NOERROR)
                    {
   				        showWaveError("waveOutPrepareHeader", ret, played, __LINE__);
                    }
			    	ret = waveOutWrite(hOut, pWH, sizeof(WAVEHDR));
                    if (ret != MMSYSERR_NOERROR)
                    {
   				        showWaveError("waveOutWrite", ret, played, __LINE__);
						/* RL < */
						if (ret == MMSYSERR_NODRIVER) {

							closeSpeakerDevices() ;
							if (openSpeakerDevices(pWH, hOut))
							{
								timeSetEvent(10, 0, TimerCallbackProc, GetCurrentThreadId(), TIME_PERIODIC);                    
							}

							continue;

						}
						/* RL > */
                    }
                    played++;
			    }

                res = MpMediaTask::signalFrameStart();

                switch (res) 
                {
                case OS_SUCCESS:
                    frameCount++;
                    break;
#ifdef DEBUG_WINDOZE /* [ */
                case OS_LIMIT_REACHED:
                    // Should bump missed frame statistic
                    osPrintf(" Frame %d: OS_LIMIT_REACHED\n", frameCount);
                   break;
                case OS_WAIT_TIMEOUT:
                    // Should bump missed frame statistic
                    osPrintf(" Frame %d: OS_WAIT_TIMEOUT\n", frameCount);
                    break;
                case OS_ALREADY_SIGNALED:
                    // Should bump missed frame statistic
                    osPrintf(" Frame %d: OS_ALREADY_SIGNALED\n", frameCount);
                    break;
                default:
                    osPrintf("Frame %d, signalFrameStart() returned %d\n",
                            frameCount, res);
                    break;
#else /* DEBUG_WINDOZE ] [ */
                case OS_LIMIT_REACHED:
                case OS_WAIT_TIMEOUT:
                case OS_ALREADY_SIGNALED:
                default:
                    // Should bump missed frame statistic
                    break;
#endif /* DEBUG_WINDOZE ] */
                }
                break;
            case WOM_CLOSE:
                // Audio device was closed on us (doesn't happen as far as I
                // know)
                bDone = true ;
                break;
            default:                
                break;
            }
        } 
        else 
        {
            // Sky is falling, kick out so that we don't spin a high priority
            // thread.
            bDone = true ;
        }
      
        // record our last ringer state
        sLastRingerEnabled = DmaTask::isRingerEnabled();
    }

    closeSpeakerDevices() ;

    bRunning = false ;

    return 0;
}