예제 #1
0
MpPortAudioMixer* MpPortAudioMixer::createMixer(MpAudioStreamId stream,
                                                int mixerIndex)
{
   // only MpPortAudioDriver can call this, and it already has a lock

   PxMixer* pxMixer = Px_OpenMixer(stream, mixerIndex);

   if (pxMixer)
   {
      MpPortAudioMixer* pMixer = new MpPortAudioMixer();
      pMixer->m_pxMixer = pxMixer;
      return pMixer;
   }

   return NULL;
}
예제 #2
0
static void AddSourcesFromStream(int deviceIndex, const PaDeviceInfo *info, std::vector<DeviceSourceMap> *maps, PaStream *stream)
{
#ifdef USE_PORTMIXER
   int i;
#endif
   DeviceSourceMap map;

   map.sourceIndex  = -1;
   map.totalSources = 0;
   // Only inputs have sources, so we call FillHostDeviceInfo with a 1 to indicate this
   FillHostDeviceInfo(&map, info, deviceIndex, 1);

#ifdef USE_PORTMIXER
   PxMixer *portMixer = Px_OpenMixer(stream, 0);
   if (!portMixer) {
      maps->push_back(map);
      return;
   }

   //if there is only one source, we don't need to concatenate the source
   //or enumerate, because it is something meaningless like 'master' 
   //(as opposed to 'mic in' or 'line in'), and the user doesn't have any choice.
   //note that some devices have no input sources at all but are still valid.
   //the behavior we do is the same for 0 and 1 source cases.
   map.totalSources = Px_GetNumInputSources(portMixer);
#endif
    
   if (map.totalSources <= 1) {
      map.sourceIndex = 0;
      maps->push_back(map);
   } 
#ifdef USE_PORTMIXER
     else {
      //open up a stream with the device so portmixer can get the info out of it.
      for (i = 0; i < map.totalSources; i++) {
         map.sourceIndex  = i;
         map.sourceString = wxString(Px_GetInputSourceName(portMixer, i), wxConvLocal);
         maps->push_back(map);
      }
   }
   Px_CloseMixer(portMixer);
#endif
}
예제 #3
0
int main(int argc, char **argv)
{
   int num_mixers;
   int i;
   PaError error;
   PortAudioStream *stream;
   int recDeviceNum;
   int playDeviceNum;
   int inputChannels;
   int outputChannels;
   int num_devices;
   int device;
   int opt;
   int opts=-1, optm=0;
   float optv=-2, opto=-2, opti=-2, opth=-2, optb=-2;
   
   printf("px_test: a program to demonstrate the capabilities of PortMixer\n");
   printf("By Dominic Mazzoni\n");
   printf("\n");
   printf("Usage:\n");
   printf("  -d [device number]\n");
   printf("  -m [mixer number]\n");
   printf("  -v [vol] (Master volume)\n");
   printf("  -o [vol] (PCM output volume)\n");
   printf("  -i [vol] (Input volume)\n");
   printf("  -s [source number] (Input source)\n");
   printf("  -h [vol] (Playthrough)\n");
   printf("  -b [bal] (Balance: -1.0....1.0)\n");
   printf("\n");
   printf("All volumes are between 0.0 and 1.0.\n");
   printf("\n");

   error = Pa_Initialize();
   if (error != 0) {
      printf("PortAudio error: %s\n", Pa_GetErrorText(error));
      return -1;
   }

   num_devices = Pa_CountDevices();

   device = Pa_GetDefaultInputDeviceID();
   recDeviceNum = paNoDevice;
   playDeviceNum = paNoDevice;
   inputChannels = 0;
   outputChannels = 0;

   while(-1 != (opt=getopt(argc, argv, "d:m:v:o:i:s:h:b:"))) {
      switch(opt) {
      case 'd':
         device = atoi(optarg);
         printf("Set device to %d\n", device);
         break;
      case 'm':
         optm = atoi(optarg);
         printf("Set mixer number to %d\n", optm);
         break;
      case 'v':
         optv = getvolarg(optarg); break;
      case 'o':
         opto = getvolarg(optarg); break;
      case 'i':
         opti = getvolarg(optarg); break;
      case 'h':
         opth = getvolarg(optarg); break;
      case 'b':
         optb = atof(optarg); break;
      case 's':
         opts = atoi(optarg); break;
      }
   }

   printf("Devices:\n");
   for(i=0; i<num_devices; i++) {
      const PaDeviceInfo* deviceInfo = Pa_GetDeviceInfo(i);
      if (i==device) {
         printf("* ");
         if (deviceInfo->maxInputChannels > 0) {
            recDeviceNum = device;
            inputChannels = deviceInfo->maxInputChannels;
         }
         if (deviceInfo->maxOutputChannels > 0) {
            playDeviceNum = device;
            outputChannels = deviceInfo->maxOutputChannels;
         }
      }
      else
         printf("  ");
      printf("Device %d: %s in=%d out=%d",
             i, deviceInfo->name,
             deviceInfo->maxInputChannels, deviceInfo->maxOutputChannels);
      if (i == Pa_GetDefaultInputDeviceID())
         printf(" (default input)");
      if (i == Pa_GetDefaultOutputDeviceID())
         printf(" (default output)");
      printf("\n");
   }
   printf("\n");
   
   error = Pa_OpenStream(&stream, recDeviceNum, inputChannels, paFloat32, NULL,
                         playDeviceNum, outputChannels, paFloat32, NULL,
                         44101, 512, 1, paClipOff | paDitherOff,
                         DummyCallbackFunc, NULL);

   if (error) {
      printf("PortAudio error %d: %s\n", error,
             Pa_GetErrorText(error));
      return -1;
   }
   
   num_mixers = Px_GetNumMixers(stream);
   printf("Number of mixers for device %d: %d\n", device, num_mixers);
   for(i=0; i<num_mixers; i++) {
      PxMixer *mixer;
      int num;
      int j;

      printf("Mixer %d: %s\n", i, Px_GetMixerName(stream, i));
      mixer = Px_OpenMixer(stream, i);
      if (!mixer) {
         printf("  Could not open mixer!\n");
         continue;
      }

      if (i == optm) {
         if (optv!=-2) {
            Px_SetMasterVolume(mixer, optv);
            printf("  Set master volume\n");
         }
         if (opto!=-2) {
            Px_SetPCMOutputVolume(mixer, opto);
            printf("  Set output volume\n");
         }
         if (opti!=-2) {
            Px_SetInputVolume(mixer, opti);
            printf("  Set input volume\n");
         }
         if (opth!=-2) {
            Px_SetPlaythrough(mixer, opth);
            printf("  Set playthrough volume\n");
         }
         if (opts!=-2) {
            Px_SetCurrentInputSource(mixer, opts);
            printf("  Set input source\n");
         }
         if (optb!=-2) {
            Px_SetOutputBalance(mixer, optb);
            printf("  Set balance\n");
         }
      }
      
      printf("  Master volume: %.2f\n", Px_GetMasterVolume(mixer));
      printf("  PCM output volume: %.2f\n", Px_GetPCMOutputVolume(mixer));

      num = Px_GetNumOutputVolumes(mixer);
      printf("  Num outputs: %d\n", num);
      for(j=0; j<num; j++) {
         printf("    Output %d (%s): %.2f\n",
                j,
                Px_GetOutputVolumeName(mixer, j),
                Px_GetOutputVolume(mixer, j));
      }

      num = Px_GetNumInputSources(mixer);
      printf("  Num input sources: %d\n", num);
      for(j=0; j<num; j++) {
         printf("    Input %d (%s) %s\n",
                j,
                Px_GetInputSourceName(mixer, j),
                (Px_GetCurrentInputSource(mixer)==j?
                 "SELECTED": ""));
      }
      printf("  Input volume: %.2f\n", Px_GetInputVolume(mixer));

      printf("  Playthrough:");
      if (Px_SupportsPlaythrough(mixer))
         printf(" %.2f\n", Px_GetPlaythrough(mixer));
      else
         printf(" not supported.\n");

      printf("  Output balance:");
      if (Px_SupportsOutputBalance(mixer))
         printf(" %.2f\n", Px_GetOutputBalance(mixer));
      else
         printf(" not supported.\n");

      Px_CloseMixer(mixer);
   }

   Pa_CloseStream(stream);

   Pa_Terminate();

   return 0;
}
예제 #4
0
static void *output_thread(void *ptr) {
	int err;
	int output_buffer_size;
#ifndef PORTAUDIO_DEV
	int num_mixers, nbVolumes, volumeIdx;
#endif
	struct timeval  now;
	struct timespec timeout;
	
	slimaudio_t *audio = (slimaudio_t *) ptr;
	audio->output_STMs = false;
	audio->output_STMu = false;

        err = Pa_Initialize();
        if (err != paNoError) {
                printf("PortAudio error4: %s Could not open any audio devices.\n", Pa_GetErrorText(err) );
                exit(-1);
        }

	if ( audio->renice )
		if ( slimproto_renice_thread (-5) ) /* Increase priority */
			fprintf(stderr, "output_thread: renice failed. Got Root?\n");

#ifndef PORTAUDIO_DEV
	DEBUGF("output_thread: output_device_id  : %i\n", audio->output_device_id );
	DEBUGF("output_thread: pa_framesPerBuffer: %lu\n", pa_framesPerBuffer );
	DEBUGF("output_thread: pa_numberOfBuffers: %lu\n", pa_numberOfBuffers );

	err = Pa_OpenStream(	&audio->pa_stream,	/* stream */
				paNoDevice,		/* input device */
				0,			/* input channels */
				0,			/* input sample format */
				NULL,			/* input driver info */
				audio->output_device_id,/* output device */
				2,			/* output channels */
				paInt16,		/* output sample format */
				NULL,			/* output driver info */
				44100.0,		/* sample rate */
				pa_framesPerBuffer,	/* frames per buffer */
				pa_numberOfBuffers,	/* number of buffers */
				paNoFlag,		/* stream flags */
				pa_callback,		/* callback */
				audio);			/* user data */
#else
	PaStreamParameters outputParameters;
	const PaDeviceInfo * paDeviceInfo;
	float newLatency;

#ifdef PADEV_WASAPI
	PaWasapiStreamInfo streamInfo;
	const PaHostApiInfo *paHostApiInfo;
#endif

	paDeviceInfo = Pa_GetDeviceInfo(audio->output_device_id);
	/* Device is not stereo or better, abort */
	if (paDeviceInfo->maxOutputChannels < 2)
	{
		printf("output_thread: PortAudio device does not support 44.1KHz, 16-bit, stereo audio.\n");
		printf("output_thread: Use -L for a list of supported audio devices, then use -o followed\n");
		printf("output_thread: by the device number listed before the colon.  See -h for details.\n");
		exit(-2);
	}
	outputParameters.device = audio->output_device_id;
#ifdef SLIMPROTO_ZONES
	outputParameters.channelCount = 2 * audio->output_num_zones;
#else
	outputParameters.channelCount = 2;
#endif
	outputParameters.sampleFormat = paInt16;
	outputParameters.suggestedLatency = paDeviceInfo->defaultHighOutputLatency;

	if ( audio->modify_latency )
	{
		newLatency = (float) audio->user_latency / 1000.0;
		if ( ( newLatency > 1.0 ) || ( newLatency <= paDeviceInfo->defaultLowOutputLatency ) )
		{
			fprintf (stderr, "User defined latency %f out of range %f-1.0, using default.\n",
					newLatency, paDeviceInfo->defaultLowOutputLatency );
			newLatency = paDeviceInfo->defaultHighOutputLatency;
		}
		outputParameters.suggestedLatency = newLatency ;
	}

#ifdef PADEV_WASAPI
	/* Use exclusive mode for WASAPI device, default is shared */

	paHostApiInfo = Pa_GetHostApiInfo ( paDeviceInfo->hostApi );
	if ( paHostApiInfo != NULL )
	{
		if ( paHostApiInfo->type == paWASAPI )
		{
			/* Use exclusive mode for WasApi device, default is shared */
			if (wasapi_exclusive)
			{
				streamInfo.size = sizeof(PaWasapiStreamInfo);
				streamInfo.hostApiType = paWASAPI;
				streamInfo.version = 1;
				streamInfo.flags = paWinWasapiExclusive;
				outputParameters.hostApiSpecificStreamInfo = &streamInfo;

				DEBUGF("WASAPI: Exclusive\n");
			}
			else
			{
				outputParameters.hostApiSpecificStreamInfo = NULL;

				DEBUGF("WASAPI: Shared\n");
			}
		}
	}
#else
	outputParameters.hostApiSpecificStreamInfo = NULL;
#endif

	DEBUGF("paDeviceInfo->deviceid %d\n", outputParameters.device);
	DEBUGF("paDeviceInfo->maxOutputChannels %i\n", paDeviceInfo->maxOutputChannels);
	DEBUGF("outputParameters.suggestedLatency %f\n", outputParameters.suggestedLatency);
	DEBUGF("paDeviceInfo->defaultHighOutputLatency %f\n", (float) paDeviceInfo->defaultHighOutputLatency);
	DEBUGF("paDeviceInfo->defaultLowOutputLatency %f\n", (float) paDeviceInfo->defaultLowOutputLatency);
	DEBUGF("paDeviceInfo->defaultSampleRate %f\n", paDeviceInfo->defaultSampleRate);

	err = Pa_OpenStream (	&audio->pa_stream,				/* stream */
				NULL,						/* inputParameters */
				&outputParameters,				/* outputParameters */
				44100.0,					/* sample rate */
				paFramesPerBufferUnspecified,			/* framesPerBuffer */
				paPrimeOutputBuffersUsingStreamCallback,	/* streamFlags */
				pa_callback,					/* streamCallback */
				audio);						/* userData */
#endif

#ifdef BSD_THREAD_LOCKING
	pthread_mutex_lock(&audio->output_mutex);
#endif

	if (err != paNoError) {
		printf("output_thread: PortAudio error1: %s\n", Pa_GetErrorText(err) );	
		exit(-1);
	}

#ifndef PORTAUDIO_DEV
	num_mixers = Px_GetNumMixers(audio->pa_stream);
	while (--num_mixers >= 0) {
		DEBUGF("Mixer: %s\n", Px_GetMixerName(audio->pa_stream, num_mixers));
	}
	
	if (audio->volume_control == VOLUME_DRIVER) {
		DEBUGF("Opening mixer.\n" );
		audio->px_mixer = Px_OpenMixer(audio->pa_stream, 0);
	}

	if (audio->px_mixer != NULL) {
		DEBUGF("Px_mixer = %p\n", audio->px_mixer);
		DEBUGF("PCM volume supported: %d.\n", 
		       Px_SupportsPCMOutputVolume(audio->px_mixer));

		nbVolumes = Px_GetNumOutputVolumes(audio->px_mixer);
		DEBUGF("Nb volumes supported: %d.\n", nbVolumes);
		for (volumeIdx=0; volumeIdx<nbVolumes; ++volumeIdx) {
			DEBUGF("Volume %d: %s\n", volumeIdx, 
				Px_GetOutputVolumeName(audio->px_mixer, volumeIdx));
		}
	}
#endif

	while (audio->output_state != QUIT) {

		switch (audio->output_state) {
			case STOPPED:
				audio->decode_num_tracks_started = 0L;
				audio->stream_samples = 0UL;
				audio->pa_streamtime_offset = audio->stream_samples;

				DEBUGF("output_thread STOPPED: %llu\n",audio->pa_streamtime_offset);

				slimaudio_buffer_set_readopt(audio->output_buffer, BUFFER_BLOCKING);

			case PAUSED:
				/* We report ourselves to the server every few seconds
				** as a keep-alive.  This is required for Squeezebox Server
				** v6.5.x although technically, "stat" is not a valid event 
				** code for the STAT Client->Server message.  This was 
				** lifted by observing how a Squeezebox3 reports itself to 
				** the server using Squeezebox Server's d_slimproto and 
				** d_slimproto_v tracing services.  Note that Squeezebox3
				** seems to report every 1 second or so, but the server only
				** drops the connection after 15-20 seconds of inactivity.
				*/
				DEBUGF("output_thread PAUSED: %llu\n",audio->pa_streamtime_offset);

			  	if (audio->keepalive_interval <= 0) {
					pthread_cond_wait(&audio->output_cond, &audio->output_mutex);
				}
				else {
					gettimeofday(&now, NULL);
					timeout.tv_sec = now.tv_sec + audio->keepalive_interval;
					timeout.tv_nsec = now.tv_usec * 1000;				
					err = pthread_cond_timedwait(&audio->output_cond,
								     &audio->output_mutex, &timeout);
					if (err == ETIMEDOUT) {
						DEBUGF("Sending keepalive. Interval=%ds.\n", audio->keepalive_interval);
						output_thread_stat(audio, "stat");
					}
				}

				break;

			case PLAY:
				audio->output_predelay_frames = audio->output_predelay_msec * 44.100;

				DEBUGF("output_thread PLAY: output_predelay_frames: %i\n",
					audio->output_predelay_frames);

				output_buffer_size = slimaudio_buffer_available(audio->output_buffer);

				DEBUGF("output_thread BUFFERING: output_buffer_size: %i output_threshold: %i",
					output_buffer_size, audio->output_threshold);
				DEBUGF(" buffering_timeout: %i\n", audio->buffering_timeout);

				if ( (output_buffer_size < audio->output_threshold) && (audio->buffering_timeout > 0) )
				{
					pthread_mutex_unlock(&audio->output_mutex);
					pthread_cond_broadcast(&audio->output_cond);

					Pa_Sleep(100);

					pthread_mutex_lock(&audio->output_mutex);
					audio->buffering_timeout--;
				}
				else
				{
					DEBUGF("output_thread PLAY: start stream: %llu\n",
						audio->pa_streamtime_offset);

					audio->buffering_timeout = BUFFERING_TIMEOUT;

					err = Pa_StartStream(audio->pa_stream);
					if (err != paNoError)
					{
						printf("output_thread: PortAudio error2: %s\n", Pa_GetErrorText(err));
						exit(-1);
					}

					audio->output_state = PLAYING;

					pthread_cond_broadcast(&audio->output_cond);
				}

				break;

			case BUFFERING:
				DEBUGF("output_thread BUFFERING: %llu\n",audio->pa_streamtime_offset);

			case PLAYING:			
				gettimeofday(&now, NULL);
				timeout.tv_sec = now.tv_sec + 1;
				timeout.tv_nsec = now.tv_usec * 1000;
				err = pthread_cond_timedwait(&audio->output_cond, &audio->output_mutex, &timeout);

				if (err == ETIMEDOUT)
				{
					DEBUGF("output_thread ETIMEDOUT-PLAYING: %llu\n",audio->pa_streamtime_offset);
					output_thread_stat(audio, "STMt");
				}

				/* Track started */				
				if (audio->output_STMs)
				{
					audio->output_STMs = false;
					audio->decode_num_tracks_started++;

					audio->replay_gain = audio->start_replay_gain;
					slimaudio_output_vol_adjust(audio);

					audio->pa_streamtime_offset = audio->stream_samples;

					DEBUGF("output_thread STMs-PLAYING: %llu\n",audio->pa_streamtime_offset);
					output_thread_stat(audio, "STMs");
				}

				/* Data underrun
				** On buffer underrun causes the server to switch to the next track.
				*/
				if (audio->output_STMu)
				{
					audio->output_STMu = false;

					audio->output_state = STOP;

					DEBUGF("output_thread STMu-PLAYING: %llu\n",audio->pa_streamtime_offset);
					output_thread_stat(audio, "STMu");

					pthread_cond_broadcast(&audio->output_cond);
				}

				break;
		
			case STOP:
#ifndef PORTAUDIO_DEV
				if ( (err = Pa_StreamActive(audio->pa_stream) ) > 0)
				{
					err = Pa_StopStream(audio->pa_stream);
					if (err != paNoError)
					{
						printf("output_thread: PortAudio error3: %s\n", Pa_GetErrorText(err) );	
						exit(-1);
					}
				}
				else
				{
					if ( err != paNoError)
					{
						printf("output_thread: PortAudio error9: %s\n",
						Pa_GetErrorText(err) );
						exit(-1);
					}
				}
#else
				if ( (err = Pa_IsStreamActive(audio->pa_stream)) > 0) {
					err = Pa_StopStream(audio->pa_stream);
					if (err != paNoError) {
						printf("output_thread[STOP]: PortAudio error3: %s\n",
									Pa_GetErrorText(err) );
						exit(-1);
					}
				} else if ( err != paNoError) {
					printf("output_thread[STOP ISACTIVE]: PortAudio error3: %s\n",
									Pa_GetErrorText(err) );
					exit(-1);
				}
#endif
				audio->output_state = STOPPED;

				DEBUGF("output_thread STOP: %llu\n",audio->pa_streamtime_offset);
				pthread_cond_broadcast(&audio->output_cond);

				break;
				
			case PAUSE:
#ifndef PORTAUDIO_DEV
				if ( (err = Pa_StreamActive(audio->pa_stream) ) > 0)
				{
					err = Pa_StopStream(audio->pa_stream);
					if (err != paNoError)
					{
						printf("output_thread: PortAudio error10: %s\n", Pa_GetErrorText(err));	
						exit(-1);
					}
				}
				else
				{
					if ( err != paNoError)
					{
						printf("output_thread: PortAudio error11: %s\n",
						Pa_GetErrorText(err) );
						exit(-1);
					}
				}
#else
				if ( (err = Pa_IsStreamActive(audio->pa_stream)) > 0) {
					err = Pa_StopStream(audio->pa_stream);
					if (err != paNoError) {
						printf("output_thread[PAUSE]: PortAudio error3: %s\n",
								Pa_GetErrorText(err) );
						exit(-1);
					}
				} else if ( err != paNoError) {
					printf("output_thread[PAUSE ISACTIVE]: PortAudio error3: %s\n",
							Pa_GetErrorText(err) );
					exit(-1);
				}
#endif
				audio->output_state = PAUSED;

				DEBUGF("output_thread PAUSE: %llu\n",audio->pa_streamtime_offset);
				pthread_cond_broadcast(&audio->output_cond);

				break;

			case QUIT:
				DEBUGF("output_thread QUIT: %llu\n",audio->pa_streamtime_offset);
				break;

		}		
	}
	pthread_mutex_unlock(&audio->output_mutex);

#ifndef PORTAUDIO_DEV	
	if (audio->px_mixer != NULL) {
		Px_CloseMixer(audio->px_mixer);
		audio->px_mixer = NULL;
	}
#endif

	err = Pa_CloseStream(audio->pa_stream);

	if (err != paNoError) {
		printf("output_thread[exit]: PortAudio error3: %s\n", Pa_GetErrorText(err) );
		exit(-1);
	}

	audio->pa_stream = NULL;
	Pa_Terminate();

	DEBUGF("output_thread: PortAudio terminated\n");

	return 0;
}
예제 #5
0
RTC::ReturnCode_t PortAudioInput::onActivated(RTC::UniqueId ec_id)
{
  RTC_DEBUG(("onActivated start"));
  PaStreamParameters inputParameters;
//  PaWasapiStreamInfo wasapiinfo;

  try {
    //m_pa_mutex.lock(); //by Irie Seisho

    m_format = getFormat(m_formatstr);
    m_totalframes = FRAMES_PER_BUFFER * m_channels;
    m_err = Pa_GetSampleSize(m_format);
    if( m_err > 0 ) {
      m_totalframes *= m_err;
    }

#if 0
    /* Find all WASAPI devices */
    const PaDeviceInfo *device;
    for ( int i = 0; i < Pa_GetDeviceCount(); ++i ) {
      device = Pa_GetDeviceInfo(i);
      if ( Pa_GetDeviceInfo(i)->hostApi == Pa_HostApiTypeIdToHostApiIndex(paWASAPI) ) {
        std::cout << "Device Index " << i << " : " << device->name << ", inch " << device->maxInputChannels << ", outch " << device->maxOutputChannels << std::endl;
      }
    }

//#if 0
    PaDeviceIndex dnum = Pa_GetDeviceCount();
    for (int i = 0; i < (int)dnum; i++) {
      std::cout << "Device Index " << i << " : " << Pa_GetDeviceInfo(i)->name << ", inch " << Pa_GetDeviceInfo(i)->maxInputChannels << ", outch " << Pa_GetDeviceInfo(i)->maxOutputChannels << std::endl;
    }
//#endif
    void *pFormat;
    unsigned int nFormatSize;
    PaDeviceIndex nDevice;
    int r = PaWasapi_GetDeviceDefaultFormat(pFormat, nFormatSize, nDevice);
#endif

    inputParameters.device = Pa_GetDefaultInputDevice(); //!< default input device
    if ( inputParameters.device < 0 ) {
      throw (paNotInitialized);
    }
    if ( m_channels > Pa_GetDeviceInfo(inputParameters.device)->maxInputChannels )
      m_channels = Pa_GetDeviceInfo(inputParameters.device)->maxInputChannels;
    inputParameters.channelCount = m_channels;
    inputParameters.sampleFormat = m_format;
    inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;

/*
    wasapiinfo.size = sizeof(PaWasapiStreamInfo);
    wasapiinfo.hostApiType = paWASAPI;
    wasapiinfo.version = 1;
    wasapiinfo.flags = paWasapiUseChannelSelectors;
    wasapiinfo.hostProcessorInput
    wasapiinfo.threadPriority
    wasapiinfo.channelMask = outputChannelSelectors;

    inputParameters.hostApiSpecificStreamInfo = wasapiinfo;
*/
    inputParameters.hostApiSpecificStreamInfo = NULL;
    m_err = Pa_OpenStream(
          &m_stream,         //!< PortAudioStream
          &inputParameters,  //!< InputParameters
          NULL,              //!< outputParameters
          m_samplerate,      //!< sampleRate
          FRAMES_PER_BUFFER, //!< framesPerBuffer
          paClipOff,         //!< streamFlags:we won't output out of range samples so don't bother clipping
//          StreamCB,          //!< streamCallback
//          this );            //!< callback userData
          NULL,              //!< streamCallback:no callback, use blocking API
          NULL );            //!< no callback, so no callback userData
    if( m_err != paNoError ) {
      throw m_err;
    }
#ifdef HAVE_LIBPORTMIXER
    m_mixer = Px_OpenMixer( m_stream, 0 );
    m_volume = Px_GetInputVolume( m_mixer );
#else
#if defined(_WIN32)
    if ( InitMixer() == true ) {
      DWORD vol;
      GetMicrophoneLevel(&vol);
    } else {
      CloseMixer();
    }
#elif defined(__linux)
    const char* sound_device_names[] = SOUND_DEVICE_NAMES;
    m_device = -1;
    m_fd = -1;
    for ( int i = 0; i < SOUND_MIXER_NRDEVICES; i ++ ) {
      std::cout << " device name : " << sound_device_names[i] << std::endl;
      if ( strcmp( "mic", sound_device_names[i] ) == 0 ) {
        m_device = i;
        break;
      }
    }
    if ( ( m_fd = open( "/dev/mixer", O_RDONLY ) ) == -1 ) {
      perror( "open" );
    }
#endif
#endif

    m_err = Pa_StartStream( m_stream );
    if( m_err != paNoError ) {
      throw m_err;
    }

    //m_pa_mutex.unlock(); //by Irie Seisho
  } catch (...) {
    std::string error_str = Pa_GetErrorText(m_err);
    RTC_WARN(("PortAudio failed onActivated:%s", error_str.c_str()));
    return RTC::RTC_ERROR;
  }

  syncflg = true;
  is_active = true;
  RTC_DEBUG(("onActivated finish"));
  return RTC::RTC_OK;
}