Пример #1
0
int getPcmParams(unsigned int i)
{
    struct pcm_params *params;
    unsigned int min;
    unsigned int max;

    params = pcm_params_get(pcmnodes[i].card, pcmnodes[i].device,
                            pcmnodes[i].flags);
    if (params == NULL)
        return -ENODEV;

    min = pcm_params_get_min(params, PCM_PARAM_RATE);
    max = pcm_params_get_max(params, PCM_PARAM_RATE);
    EXPECT_LE(min, max);
    /* printf("        Rate:\tmin=%uHz\tmax=%uHz\n", min, max); */
    min = pcm_params_get_min(params, PCM_PARAM_CHANNELS);
    max = pcm_params_get_max(params, PCM_PARAM_CHANNELS);
    EXPECT_LE(min, max);
    /* printf("    Channels:\tmin=%u\t\tmax=%u\n", min, max); */
    min = pcm_params_get_min(params, PCM_PARAM_SAMPLE_BITS);
    max = pcm_params_get_max(params, PCM_PARAM_SAMPLE_BITS);
    EXPECT_LE(min, max);
    /* printf(" Sample bits:\tmin=%u\t\tmax=%u\n", min, max); */
    min = pcm_params_get_min(params, PCM_PARAM_PERIOD_SIZE);
    max = pcm_params_get_max(params, PCM_PARAM_PERIOD_SIZE);
    EXPECT_LE(min, max);
    /* printf(" Period size:\tmin=%u\t\tmax=%u\n", min, max); */
    min = pcm_params_get_min(params, PCM_PARAM_PERIODS);
    max = pcm_params_get_max(params, PCM_PARAM_PERIODS);
    EXPECT_LE(min, max);
    /* printf("Period count:\tmin=%u\t\tmax=%u\n", min, max); */

    pcm_params_free(params);
    return 0;
}
status_t AudioALSAPlaybackHandlerBTSCO::open()
{
    ALOGD("+%s(), mDevice = 0x%x", __FUNCTION__, mStreamAttributeSource->output_devices);

    // debug pcm dump
    OpenPCMDump(LOG_TAG);

    int pcmindex = AudioALSADeviceParser::getInstance()->GetPcmIndexByString(keypcmVOIPCallBTPlayback);
    int cardindex = AudioALSADeviceParser::getInstance()->GetCardIndexByString(keypcmVOIPCallBTPlayback);

    struct pcm_params *params;
    params = pcm_params_get(cardindex, pcmindex,  PCM_OUT);
    if (params == NULL)
    {
        ALOGD("Device does not exist.\n");
    }
    mStreamAttributeTarget.buffer_size = pcm_params_get_max(params, PCM_PARAM_BUFFER_BYTES);
    ALOGD("buffersizemax = %d", mStreamAttributeTarget.buffer_size);
    pcm_params_free(params);

    // HW attribute config // TODO(Harvey): query this
#ifdef PLAYBACK_USE_24BITS_ONLY
    mStreamAttributeTarget.audio_format = AUDIO_FORMAT_PCM_8_24_BIT;
#else
    mStreamAttributeTarget.audio_format = AUDIO_FORMAT_PCM_16_BIT;
#endif
    mStreamAttributeTarget.audio_channel_mask = AUDIO_CHANNEL_IN_STEREO;
    mStreamAttributeTarget.num_channels = android_audio_legacy::AudioSystem::popCount(mStreamAttributeTarget.audio_channel_mask);
    mStreamAttributeTarget.sample_rate = mWCNChipController->GetBTCurrentSamplingRateNumber();


    // HW pcm config
    mConfig.channels = mStreamAttributeTarget.num_channels;
    mConfig.rate = mStreamAttributeTarget.sample_rate;

    mConfig.period_count = 2;
    mConfig.period_size = (mStreamAttributeTarget.buffer_size / (mConfig.channels * mConfig.period_count)) / ((mStreamAttributeTarget.audio_format == AUDIO_FORMAT_PCM_16_BIT) ? 2 : 4);

    mConfig.format = transferAudioFormatToPcmFormat(mStreamAttributeTarget.audio_format);

    mConfig.start_threshold = 0;
    mConfig.stop_threshold = 0;
    mConfig.silence_threshold = 0;
    ALOGD("%s(), mConfig: channels = %d, rate = %d, period_size = %d, period_count = %d, format = %d",
          __FUNCTION__, mConfig.channels, mConfig.rate, mConfig.period_size, mConfig.period_count, mConfig.format);

    // SRC
    initBliSrc();

    // bit conversion
    initBitConverter();

    // open pcm driver
    openPcmDriver(pcmindex);

    ALOGD("-%s()", __FUNCTION__);
    return NO_ERROR;
}
Пример #3
0
static int validate_output_hardware_params(struct stream_out *out)
{
    struct audio_device *adev = out->dev;
    struct pcm_params *params;
    unsigned int min;
    unsigned int max;

    params = pcm_params_get(adev->card, adev->device, PCM_OUT);
    if (params == NULL) {
        ALOGW("Device does not exist.\n");
        return -1;
    }

    //always open the device with max capabilities if
    // input params are not supported

    min = pcm_params_get_min(params, PCM_PARAM_RATE);
    max = pcm_params_get_max(params, PCM_PARAM_RATE);
    ALOGI("hw supported Rate:\tmin=%uHz\tmax=%uHz\n", min, max);
    if((out->pcm_config.rate < min) || (out->pcm_config.rate > max)) {
       out->pcm_config.rate = max;
    }

    min = pcm_params_get_min(params, PCM_PARAM_CHANNELS);
    max = pcm_params_get_max(params, PCM_PARAM_CHANNELS);
    ALOGI("hw supported Channels:\tmin=%u\t\tmax=%u\n", min, max);
    if((out->pcm_config.channels < min) || (out->pcm_config.channels > max)) {
       out->pcm_config.channels = max;
    }

    min = pcm_params_get_min(params, PCM_PARAM_SAMPLE_BITS);
    max = pcm_params_get_max(params, PCM_PARAM_SAMPLE_BITS);
    ALOGI("hw supported Sample bits:\tmin=%u\t\tmax=%u\n", min, max);

    unsigned int bits_per_sample = format_to_bits(out->pcm_config.format);

    if((bits_per_sample < min) || (bits_per_sample > max)) {
       bits_per_sample = max;
    }

    out->pcm_config.format = bits_to_format(bits_per_sample);

   ALOGV("%s exit supported params %d,%d,%d,%d,%d",__func__,
          out->pcm_config.channels,
          out->pcm_config.rate,
          out->pcm_config.period_size,
          out->pcm_config.period_count,
          out->pcm_config.format);

    pcm_params_free(params);

    return 0;

}
Пример #4
0
static int init_tinyalsa(out123_handle* ao)
{
	if (ao==NULL) return -1;

	/* Set callbacks */
	ao->open = open_tinyalsa;
	ao->flush = flush_tinyalsa;
	ao->write = write_tinyalsa;
	ao->get_formats = get_formats_tinyalsa;
	ao->close = close_tinyalsa;
	ao->deinit = deinit_tinyalsa;

	/* Allocate memory for data structure */
	ao->userptr = malloc( sizeof( mpg123_tinyalsa_t ) );
	if(ao->userptr==NULL)
	{
		if(!AOQUIET)
			error("failed to malloc memory for 'mpg123_tinyalsa_t'");
		return -1;
	}
	memset( ao->userptr, 0, sizeof(mpg123_tinyalsa_t) );

	/* Set card and device */
	mpg123_tinyalsa_t* ta = (mpg123_tinyalsa_t*)ao->userptr;

	ta->card = 0;
	ta->device = 0;

	if (ao->device)
	{
		char *ptr = ao->device;
		ta->card = (unsigned int)strtol(ptr, &ptr, 10);
		if (strlen(ptr) > 0)
		{
	    		ta->device = (unsigned int)strtol(++ptr, &ptr, 10);
	  	}
	}

	/* Get card/device parameters */
	ta->params = pcm_params_get(ta->card, ta->device, PCM_OUT);
	if (ta->params == NULL)
	{
		if(!AOQUIET)
			error2( "(params) Unable to open card %u PCM device %u.\n"
			,	ta->card, ta->device );
		return -1;
	}

	/* Success */
	return 0;
}
/*
 * Reads and decodes configuration info from the specified ALSA card/device.
 */
static int read_alsa_device_config(alsa_device_profile * profile, struct pcm_config * config)
{
    ALOGV("usb:audio_hw - read_alsa_device_config(c:%d d:%d t:0x%X)",
          profile->card, profile->device, profile->direction);

    if (profile->card < 0 || profile->device < 0) {
        return -EINVAL;
    }

    struct pcm_params * alsa_hw_params =
        pcm_params_get(profile->card, profile->device, profile->direction);
    if (alsa_hw_params == NULL) {
        return -EINVAL;
    }

    profile->min_period_size = pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIOD_SIZE);
    profile->max_period_size = pcm_params_get_max(alsa_hw_params, PCM_PARAM_PERIOD_SIZE);

    profile->min_channel_count = pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS);
    profile->max_channel_count = pcm_params_get_max(alsa_hw_params, PCM_PARAM_CHANNELS);

    int ret = 0;

    /*
     * This Logging will be useful when testing new USB devices.
     */
#ifdef LOG_PCM_PARAMS
    log_pcm_params(alsa_hw_params);
#endif

    config->channels = pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS);
    config->rate = pcm_params_get_min(alsa_hw_params, PCM_PARAM_RATE);
    config->period_size = profile_calc_min_period_size(profile, config->rate);
    config->period_count = pcm_params_get_min(alsa_hw_params, PCM_PARAM_PERIODS);
    config->format = get_pcm_format_for_mask(pcm_params_get_mask(alsa_hw_params, PCM_PARAM_FORMAT));
#ifdef LOG_PCM_PARAMS
    log_pcm_config(config, "read_alsa_device_config");
#endif
    if (config->format == PCM_FORMAT_INVALID) {
        ret = -EINVAL;
    }

    pcm_params_free(alsa_hw_params);

    return ret;
}
Пример #6
0
uint32_t SpeechANCController::ConfigPCM(String8 stringPCM, int *buffer_size)
{
    struct pcm_params *params;
    int pcmindex = AudioALSADeviceParser::getInstance()->GetPcmIndexByString(stringPCM);
    int cardindex = AudioALSADeviceParser::getInstance()->GetCardIndexByString(stringPCM);
    params = pcm_params_get(cardindex, pcmindex,  PCM_IN);
    if (params == NULL)
    {
        ALOGD("Device does not exist.\n");
    }
    *buffer_size = pcm_params_get_max(params, PCM_PARAM_BUFFER_BYTES);
    pcm_params_free(params);
    //    ALOGD("%s(), pcmindex(%d), cardindex(%d), buffersizemax(%d)", __FUNCTION__, pcmindex, cardindex, *buffer_size);
    ALOGD("%s(), %s = pcmindex(%d), cardindex(%d), buffersizemax(%d)", __FUNCTION__, stringPCM.string(), pcmindex, cardindex, *buffer_size);

    return pcmindex;
}
bool profile_read_device_info(alsa_device_profile* profile)
{
    if (!profile_is_initialized(profile)) {
        return false;
    }

    /* let's get some defaults */
    read_alsa_device_config(profile, &profile->default_config);
    ALOGV("default_config chans:%d rate:%d format:%d count:%d size:%d",
          profile->default_config.channels, profile->default_config.rate,
          profile->default_config.format, profile->default_config.period_count,
          profile->default_config.period_size);

    struct pcm_params * alsa_hw_params = pcm_params_get(profile->card,
                                                        profile->device,
                                                        profile->direction);
    if (alsa_hw_params == NULL) {
        return false;
    }

    /* Formats */
    struct pcm_mask * format_mask = pcm_params_get_mask(alsa_hw_params, PCM_PARAM_FORMAT);
    profile_enum_sample_formats(profile, format_mask);

    /* Channels */
    profile_enum_channel_counts(
            profile, pcm_params_get_min(alsa_hw_params, PCM_PARAM_CHANNELS),
            pcm_params_get_max(alsa_hw_params, PCM_PARAM_CHANNELS));

    /* Sample Rates */
    profile_enum_sample_rates(
            profile, pcm_params_get_min(alsa_hw_params, PCM_PARAM_RATE),
            pcm_params_get_max(alsa_hw_params, PCM_PARAM_RATE));

    profile->is_valid = true;

    return true;
}
int sample_is_playable(unsigned int card, unsigned int device, unsigned int channels,
                        unsigned int rate, unsigned int bits, unsigned int period_size,
                        unsigned int period_count)
{
    struct pcm_params *params;
    int can_play;

    params = pcm_params_get(card, device, PCM_OUT);
    if (params == NULL) {
        fprintf(stderr, "Unable to open PCM device %u.\n", device);
        return 0;
    }

    can_play = check_param(params, PCM_PARAM_RATE, rate, "Sample rate", "Hz");
    can_play &= check_param(params, PCM_PARAM_CHANNELS, channels, "Sample", " channels");
    can_play &= check_param(params, PCM_PARAM_SAMPLE_BITS, bits, "Bitrate", " bits");
    can_play &= check_param(params, PCM_PARAM_PERIOD_SIZE, period_size, "Period size", "Hz");
    can_play &= check_param(params, PCM_PARAM_PERIODS, period_count, "Period count", "Hz");

    pcm_params_free(params);

    return can_play;
}
void AudioALSAPlaybackHandlerNormal::OpenHpImpeDancePcm(void)
{
    ALOGD("OpenHpImpeDancePcm");
    // Don't lock Sram/Dram lock here, it would be locked by caller function

    int pcmindex = AudioALSADeviceParser::getInstance()->GetPcmIndexByString(keypcmHpimpedancePlayback);
    int cardindex = AudioALSADeviceParser::getInstance()->GetCardIndexByString(keypcmHpimpedancePlayback);
    struct pcm_params *params;
    params = pcm_params_get(cardindex, pcmindex,  PCM_OUT);
    if (params == NULL)
    {
        ALOGD("Device does not exist.\n");
    }
    int buffer_size = pcm_params_get_max(params, PCM_PARAM_BUFFER_BYTES);
    ALOGD("buffer_size = %d", buffer_size);
    pcm_params_free(params);
    // HW pcm config
    mHpImpedanceConfig.channels = 2;
    mHpImpedanceConfig.rate = mStreamAttributeSource->sample_rate;
    mHpImpedanceConfig.period_count = 2;
    mHpImpedanceConfig.period_size = (buffer_size / (mHpImpedanceConfig.channels * mHpImpedanceConfig.period_count)) / 2;
    mHpImpedanceConfig.format = PCM_FORMAT_S16_LE;
    mHpImpedanceConfig.start_threshold = 0;
    mHpImpedanceConfig.stop_threshold = 0;
    mHpImpedanceConfig.silence_threshold = 0;
    ALOGD("%s(), mHpImpedanceConfig: channels = %d, rate = %d, period_size = %d, period_count = %d, format = %d",
          __FUNCTION__, mHpImpedanceConfig.channels, mHpImpedanceConfig.rate, mHpImpedanceConfig.period_size, mHpImpedanceConfig.period_count, mHpImpedanceConfig.format);
    // open pcm driver
    mHpImpeDancePcm = pcm_open(cardindex, pcmindex, PCM_OUT, &mHpImpedanceConfig);
    if (mHpImpeDancePcm == NULL)
    {
        ALOGE("%s(), mPcm == NULL!!", __FUNCTION__);
    }
    ALOGD("-%s(), mPcm = %p", __FUNCTION__, mHpImpeDancePcm);
    ASSERT(mHpImpeDancePcm != NULL);
    pcm_start(mHpImpeDancePcm);
}
status_t AudioALSAPlaybackHandlerNormal::open()
{
    ALOGD("+%s(), mDevice = 0x%x", __FUNCTION__, mStreamAttributeSource->output_devices);
    AudioAutoTimeoutLock _l(*AudioALSADriverUtility::getInstance()->getStreamSramDramLock());

    // debug pcm dump
    OpenPCMDump(LOG_TAG);
    // acquire pmic clk
    mHardwareResourceManager->EnableAudBufClk(true);
    HpImpeDanceDetect();
    int pcmindex = AudioALSADeviceParser::getInstance()->GetPcmIndexByString(keypcmI2S0Dl1Playback);
    int cardindex = AudioALSADeviceParser::getInstance()->GetCardIndexByString(keypcmI2S0Dl1Playback);

    ALOGD("AudioALSAPlaybackHandlerNormal::open() pcmindex = %d", pcmindex);
    ListPcmDriver(cardindex, pcmindex);

    struct pcm_params *params;
    params = pcm_params_get(cardindex, pcmindex,  PCM_OUT);
    if (params == NULL)
    {
        ALOGD("Device does not exist.\n");
    }
    mStreamAttributeTarget.buffer_size = pcm_params_get_max(params, PCM_PARAM_BUFFER_BYTES);
    pcm_params_free(params);

    // HW attribute config // TODO(Harvey): query this
#ifdef PLAYBACK_USE_24BITS_ONLY
    mStreamAttributeTarget.audio_format = AUDIO_FORMAT_PCM_8_24_BIT;
#else
    mStreamAttributeTarget.audio_format = (mStreamAttributeSource->audio_format == AUDIO_FORMAT_PCM_32_BIT) ? AUDIO_FORMAT_PCM_8_24_BIT : AUDIO_FORMAT_PCM_16_BIT;
#endif
    mStreamAttributeTarget.audio_channel_mask = AUDIO_CHANNEL_IN_STEREO;
    mStreamAttributeTarget.num_channels = android_audio_legacy::AudioSystem::popCount(mStreamAttributeTarget.audio_channel_mask);

    mStreamAttributeTarget.sample_rate = ChooseTargetSampleRate(mStreamAttributeSource->sample_rate,mStreamAttributeSource->output_devices);

    // HW pcm config
    mConfig.channels = mStreamAttributeTarget.num_channels;
    mConfig.rate = mStreamAttributeTarget.sample_rate;

    // Buffer size: 1536(period_size) * 2(ch) * 4(byte) * 2(period_count) = 24 kb

    mConfig.period_count = 2;
    mConfig.period_size = (mStreamAttributeTarget.buffer_size / (mConfig.channels * mConfig.period_count)) / ((mStreamAttributeTarget.audio_format == AUDIO_FORMAT_PCM_16_BIT) ? 2 : 4);

    mConfig.format = transferAudioFormatToPcmFormat(mStreamAttributeTarget.audio_format);

    mConfig.start_threshold = 0;
    mConfig.stop_threshold = 0;
    mConfig.silence_threshold = 0;
    ALOGD("%s(), mConfig: channels = %d, rate = %d, period_size = %d, period_count = %d, format = %d",
          __FUNCTION__, mConfig.channels, mConfig.rate, mConfig.period_size, mConfig.period_count, mConfig.format);

    // post processing
    initPostProcessing();

#if defined(MTK_SPEAKER_MONITOR_SUPPORT)
    unsigned int fc, bw;
    int th;
    if (mAudioFilterManagerHandler)
    {
        AudioALSASpeakerMonitor::getInstance()->GetFilterParam(&fc, &bw, &th);
        ALOGD("%s(), fc %d bw %d, th %d", __FUNCTION__, fc, bw, th);
        mAudioFilterManagerHandler->setSpkFilterParam(fc, bw, th);
    }
#endif

    // SRC
    initBliSrc();

    // bit conversion
    initBitConverter();

    initDataPending();

    // disable lowjitter mode
    SetLowJitterMode(true, mStreamAttributeTarget.sample_rate);

    // open pcm driver
    openPcmDriver(pcmindex);

    // open codec driver
    mHardwareResourceManager->startOutputDevice(mStreamAttributeSource->output_devices, mStreamAttributeTarget.sample_rate);


    //============Voice UI&Unlock REFERECE=============
    AudioVUnlockDL *VUnlockhdl = AudioVUnlockDL::getInstance();
    if (VUnlockhdl != NULL)
    {
        VUnlockhdl->SetInputStandBy(false);
        VUnlockhdl-> GetSRCInputParameter(mStreamAttributeTarget.sample_rate, mStreamAttributeTarget.num_channels, mStreamAttributeTarget.audio_format);
        VUnlockhdl->GetFirstDLTime();
    }
    //===========================================


    ALOGD("-%s()", __FUNCTION__);
    return NO_ERROR;
}
Пример #11
0
static gboolean
gst_tinyalsa_sink_prepare (GstAudioSink * asink, GstAudioRingBufferSpec * spec)
{
  GstTinyalsaSink *sink = GST_TINYALSA_SINK (asink);
  struct pcm_config config = { 0, };
  struct pcm_params *params = NULL;
  int period_size_min, period_size_max;
  int periods_min, periods_max;

  pcm_config_from_spec (&config, spec);

  GST_DEBUG_OBJECT (sink, "Requesting %u periods of %u frames",
      config.period_count, config.period_size);

  params = pcm_params_get (sink->card, sink->device, PCM_OUT);
  if (!params)
    GST_ERROR_OBJECT (sink, "Could not get PCM params");

  period_size_min = pcm_params_get_min (params, PCM_PARAM_PERIOD_SIZE);
  period_size_max = pcm_params_get_max (params, PCM_PARAM_PERIOD_SIZE);
  periods_min = pcm_params_get_min (params, PCM_PARAM_PERIODS);
  periods_max = pcm_params_get_max (params, PCM_PARAM_PERIODS);

  pcm_params_free (params);

  /* Snap period size/count to the permitted range */
  config.period_size =
      CLAMP (config.period_size, period_size_min, period_size_max);
  config.period_count = CLAMP (config.period_count, periods_min, periods_max);

  /* mutex with getcaps */
  GST_OBJECT_LOCK (sink);

  sink->pcm = pcm_open (sink->card, sink->device, PCM_OUT | PCM_NORESTART,
      &config);

  GST_OBJECT_UNLOCK (sink);

  if (!sink->pcm || !pcm_is_ready (sink->pcm)) {
    GST_ERROR_OBJECT (sink, "Could not open device: %s",
        pcm_get_error (sink->pcm));
    goto fail;
  }

  if (pcm_prepare (sink->pcm) < 0) {
    GST_ERROR_OBJECT (sink, "Could not prepare device: %s",
        pcm_get_error (sink->pcm));
    goto fail;
  }

  spec->segsize = pcm_frames_to_bytes (sink->pcm, config.period_size);
  spec->segtotal = config.period_count;

  GST_DEBUG_OBJECT (sink, "Configured for %u periods of %u frames",
      config.period_count, config.period_size);

  return TRUE;

fail:
  if (sink->pcm)
    pcm_close (sink->pcm);

  return FALSE;
}
Пример #12
0
static GstCaps *
gst_tinyalsa_sink_getcaps (GstBaseSink * bsink, GstCaps * filter)
{
  GstTinyalsaSink *sink = GST_TINYALSA_SINK (bsink);
  GstCaps *caps = NULL;
  GValue formats = { 0, };
  GValue format = { 0, };
  struct pcm_params *params = NULL;
  struct pcm_mask *mask;
  int rate_min, rate_max, channels_min, channels_max;
  guint16 m;

  GST_DEBUG_OBJECT (sink, "Querying caps");

  GST_OBJECT_LOCK (sink);

  if (sink->cached_caps) {
    GST_DEBUG_OBJECT (sink, "Returning cached caps");
    caps = gst_caps_ref (sink->cached_caps);
    goto done;
  }

  if (sink->pcm) {
    /* We can't query the device while it's open, so return current caps */
    caps = gst_pad_get_current_caps (GST_BASE_SINK_PAD (bsink));
    goto done;
  }

  params = pcm_params_get (sink->card, sink->device, PCM_OUT);
  if (!params) {
    GST_ERROR_OBJECT (sink, "Could not get PCM params");
    goto done;
  }

  mask = pcm_params_get_mask (params, PCM_PARAM_FORMAT);
  m = (mask->bits[1] << 8) | mask->bits[0];

  if (!(m & SNDRV_PCM_FORMAT_ANY)) {
    GST_ERROR_OBJECT (sink, "Could not find any supported format");
    goto done;
  }

  caps = gst_caps_new_empty_simple ("audio/x-raw");

  g_value_init (&formats, GST_TYPE_LIST);
  g_value_init (&format, G_TYPE_STRING);

  if (m & (1 << SNDRV_PCM_FORMAT_S8)) {
    g_value_set_static_string (&format, "S8");
    gst_value_list_prepend_value (&formats, &format);
  }
  if (m & (1 << SNDRV_PCM_FORMAT_S16_LE)) {
    g_value_set_static_string (&format, "S16LE");
    gst_value_list_prepend_value (&formats, &format);
  }
  if (m & (1 << SNDRV_PCM_FORMAT_S24_LE)) {
    g_value_set_static_string (&format, "S24_32LE");
    gst_value_list_prepend_value (&formats, &format);
  }
  if (m & (1 << SNDRV_PCM_FORMAT_S32_LE)) {
    g_value_set_static_string (&format, "S32LE");
    gst_value_list_prepend_value (&formats, &format);
  }

  gst_caps_set_value (caps, "format", &formats);

  g_value_unset (&format);
  g_value_unset (&formats);

  /* This is a bit of a lie, since the device likely only supports some
   * standard rates in this range. We should probably filter the range to
   * those, standard audio rates but even that isn't guaranteed to be accurate.
   */
  rate_min = pcm_params_get_min (params, PCM_PARAM_RATE);
  rate_max = pcm_params_get_max (params, PCM_PARAM_RATE);

  if (rate_min == rate_max)
    gst_caps_set_simple (caps, "rate", G_TYPE_INT, rate_min, NULL);
  else
    gst_caps_set_simple (caps, "rate", GST_TYPE_INT_RANGE, rate_min, rate_max,
        NULL);

  channels_min = pcm_params_get_min (params, PCM_PARAM_CHANNELS);
  channels_max = pcm_params_get_max (params, PCM_PARAM_CHANNELS);

  if (channels_min == channels_max)
    gst_caps_set_simple (caps, "channels", G_TYPE_INT, channels_min, NULL);
  else
    gst_caps_set_simple (caps, "channels", GST_TYPE_INT_RANGE, channels_min,
        channels_max, NULL);

  gst_caps_replace (&sink->cached_caps, caps);

done:
  GST_OBJECT_UNLOCK (sink);

  GST_DEBUG_OBJECT (sink, "Got caps %" GST_PTR_FORMAT, caps);

  if (caps && filter) {
    GstCaps *intersection =
        gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);

    gst_caps_unref (caps);
    caps = intersection;
  }

  if (params)
    pcm_params_free (params);

  return caps;
}
Пример #13
0
int main(int argc, char **argv)
{
    unsigned int device = 0;
    unsigned int card = 0;
    int i;

    if (argc < 3) {
        fprintf(stderr, "Usage: %s -D card -d device\n", argv[0]);
        return 1;
    }

    /* parse command line arguments */
    argv += 1;
    while (*argv) {
        if (strcmp(*argv, "-D") == 0) {
            argv++;
            if (*argv)
                card = atoi(*argv);
        }
        if (strcmp(*argv, "-d") == 0) {
            argv++;
            if (*argv)
                device = atoi(*argv);
        }
        if (*argv)
            argv++;
    }

    printf("Info for card %u, device %u:\n", card, device);

    for (i = 0; i < 2; i++) {
        struct pcm_params *params;
        struct pcm_mask *m;
        unsigned int min;
        unsigned int max;

        printf("\nPCM %s:\n", i == 0 ? "out" : "in");

        params = pcm_params_get(card, device, i == 0 ? PCM_OUT : PCM_IN);
        if (params == NULL) {
            printf("Device does not exist.\n");
            continue;
        }

        m = pcm_params_get_mask(params, PCM_PARAM_ACCESS);
        if (m) { /* bitmask, refer to SNDRV_PCM_ACCESS_*, generally interleaved */
            printf("      Access:\t%#08x\n", m->bits[0]);
        }
        m = pcm_params_get_mask(params, PCM_PARAM_FORMAT);
        if (m) { /* bitmask, refer to: SNDRV_PCM_FORMAT_* */
            unsigned j, k, count = 0;
            const unsigned bitcount = sizeof(m->bits[0]) * 8;

            /* we only check first two format masks (out of 8) - others are zero. */
            printf("   Format[0]:\t%#08x\n", m->bits[0]);
            printf("   Format[1]:\t%#08x\n", m->bits[1]);

            /* print friendly format names, if they exist */
            for (k = 0; k < 2; ++k) {
                for (j = 0; j < bitcount; ++j) {
                    const char *name;

                    if (m->bits[k] & (1 << j)) {
                        name = pcm_get_format_name(j + k*bitcount);
                        if (name) {
                            if (count++ == 0) {
                                printf(" Format Name:\t");
                            } else {
                                printf (", ");
                            }
                            printf("%s", name);
                        }
                    }
                }
            }
            if (count) {
                printf("\n");
            }
        }
        m = pcm_params_get_mask(params, PCM_PARAM_SUBFORMAT);
        if (m) { /* bitmask, should be 1: SNDRV_PCM_SUBFORMAT_STD */
            printf("   Subformat:\t%#08x\n", m->bits[0]);
        }
        min = pcm_params_get_min(params, PCM_PARAM_RATE);
        max = pcm_params_get_max(params, PCM_PARAM_RATE);
        printf("        Rate:\tmin=%uHz\tmax=%uHz\n", min, max);
        min = pcm_params_get_min(params, PCM_PARAM_CHANNELS);
        max = pcm_params_get_max(params, PCM_PARAM_CHANNELS);
        printf("    Channels:\tmin=%u\t\tmax=%u\n", min, max);
        min = pcm_params_get_min(params, PCM_PARAM_SAMPLE_BITS);
        max = pcm_params_get_max(params, PCM_PARAM_SAMPLE_BITS);
        printf(" Sample bits:\tmin=%u\t\tmax=%u\n", min, max);
        min = pcm_params_get_min(params, PCM_PARAM_PERIOD_SIZE);
        max = pcm_params_get_max(params, PCM_PARAM_PERIOD_SIZE);
        printf(" Period size:\tmin=%u\t\tmax=%u\n", min, max);
        min = pcm_params_get_min(params, PCM_PARAM_PERIODS);
        max = pcm_params_get_max(params, PCM_PARAM_PERIODS);
        printf("Period count:\tmin=%u\t\tmax=%u\n", min, max);

        pcm_params_free(params);
    }

    return 0;
}
status_t AudioALSAPlaybackHandlerSphDL::open()
{
    ALOGD("+%s(), mDevice = 0x%x", __FUNCTION__, mStreamAttributeSource->output_devices);
    // debug pcm dump
    OpenPCMDump(LOG_TAG);
    int pcmindex = AudioALSADeviceParser::getInstance()->GetPcmIndexByString(keypcmI2S0Dl1Playback);
    int cardindex = AudioALSADeviceParser::getInstance()->GetCardIndexByString(keypcmI2S0Dl1Playback);
    ALOGD("AudioALSAPlaybackHandlerSphDL::open() pcmindex = %d", pcmindex);
    ListPcmDriver(cardindex, pcmindex);

    struct pcm_params *params;
    params = pcm_params_get(cardindex, pcmindex,  PCM_OUT);
    if (params == NULL)
    {
        ALOGD("Device does not exist.\n");
    }
    mStreamAttributeTarget.buffer_size = pcm_params_get_max(params, PCM_PARAM_BUFFER_BYTES);
    ALOGD("buffersizemax = %d", mStreamAttributeTarget.buffer_size);
    pcm_params_free(params);


    // HW attribute config // TODO(Harvey): query this
    mStreamAttributeTarget.audio_format = AUDIO_FORMAT_PCM_16_BIT;
    mStreamAttributeTarget.audio_channel_mask = AUDIO_CHANNEL_IN_MONO;
    mStreamAttributeTarget.num_channels = android_audio_legacy::AudioSystem::popCount(mStreamAttributeTarget.audio_channel_mask);
    mStreamAttributeTarget.sample_rate = mStreamAttributeSource->sample_rate; // same as source stream


    // HW pcm config
    mConfig.channels = mStreamAttributeTarget.num_channels;
    mConfig.rate = mStreamAttributeTarget.sample_rate;

    // Buffer size: 1536(period_size) * 2(ch) * 4(byte) * 2(period_count) = 24 kb

    mConfig.period_count = 4;
    //mConfig.period_size = (0x4000/(mConfig.channels*mConfig.period_count))/((mStreamAttributeTarget.audio_format == AUDIO_FORMAT_PCM_16_BIT) ? 2 : 4);
    mConfig.period_size = 512;

    mConfig.format = transferAudioFormatToPcmFormat(mStreamAttributeTarget.audio_format);

    mConfig.start_threshold = 0;
    mConfig.stop_threshold = 0;
    mConfig.silence_threshold = 0;
    ALOGD("%s(), mConfig: channels = %d, rate = %d, period_size = %d, period_count = %d, format = %d",
          __FUNCTION__, mConfig.channels, mConfig.rate, mConfig.period_size, mConfig.period_count, mConfig.format);


    // post processing
    initPostProcessing();

#if defined(MTK_SPEAKER_MONITOR_SUPPORT)
    unsigned int fc, bw;
    int th;
    if (mAudioFilterManagerHandler)
    {
        AudioALSASpeakerMonitor::getInstance()->GetFilterParam(&fc, &bw, &th);
        ALOGD("%s(), fc %d bw %d, th %d", __FUNCTION__, fc, bw, th);
        mAudioFilterManagerHandler->setSpkFilterParam(fc, bw, th);
    }
#endif

    // SRC
    initBliSrc();


    // bit conversion
    initBitConverter();


    // open pcm driver
    openPcmDriver(pcmindex);

    //Echo reference path
    if (mixer_ctl_set_enum_by_string(mixer_get_ctl_by_name(mMixer, "Audio_Dl1_MD_Echo_Ref_Switch"), "On"))
    {
        ALOGE("Error: Audio_Dl1_MD_Echo_Ref_Switch invalid value");
    }

    // open codec driver
    // Don't startoutputDevice here, let speech driver to open.
    mHardwareResourceManager->startOutputDevice(mStreamAttributeSource->output_devices, mStreamAttributeTarget.sample_rate);

    ALOGD("-%s()", __FUNCTION__);
    return NO_ERROR;
}
status_t AudioALSAPlaybackHandlerOffload::open()
{
    ALOGD("+%s(), mDevice = 0x%x", __FUNCTION__, mStreamAttributeSource->output_devices);
    ALOGD("%s(), mStreamAttributeSource: format = %d",__FUNCTION__, mStreamAttributeSource->audio_format);
    AudioAutoTimeoutLock _l(*AudioALSADriverUtility::getInstance()->getStreamSramDramLock());
    // debug pcm dump
    OpenPCMDump(LOG_TAG);
    // acquire pmic clk
    mHardwareResourceManager->EnableAudBufClk(true);
    //doug to check
    
    //HpImpeDanceDetect();  //doug to check
#if 1
    int pcmindex = AudioALSADeviceParser::getInstance()->GetPcmIndexByString(keypcmDl1Meida);
    int cardindex = AudioALSADeviceParser::getInstance()->GetCardIndexByString(keypcmDl1Meida);

    ALOGD("AudioALSAPlaybackHandlerOffload::open() pcmindex = %d", pcmindex);
    ListPcmDriver(cardindex, pcmindex);

    struct pcm_params *params;
    params = pcm_params_get(cardindex, pcmindex,  PCM_OUT);
    if (params == NULL)
    {
        ALOGD("Device does not exist.\n");
    }
    mStreamAttributeTarget.buffer_size = pcm_params_get_max(params, PCM_PARAM_BUFFER_BYTES);
    ALOGD("%s buffersizemax = %d", __FUNCTION__, mStreamAttributeTarget.buffer_size);
    pcm_params_free(params);
#endif
    //mStreamAttributeTarget.buffer_size = 32768;

//#ifdef PLAYBACK_USE_24BITS_ONLY
        //mStreamAttributeTarget.audio_format = AUDIO_FORMAT_PCM_32_BIT;
        mStreamAttributeTarget.audio_format = AUDIO_FORMAT_PCM_8_24_BIT;
        //mStreamAttributeTarget.audio_format = AUDIO_FORMAT_PCM_16_BIT;
//#else
	//	mStreamAttributeTarget.audio_format = (mStreamAttributeSource->audio_format == AUDIO_FORMAT_PCM_32_BIT) ? AUDIO_FORMAT_PCM_8_24_BIT : AUDIO_FORMAT_PCM_16_BIT;
//#endif


    mStreamAttributeTarget.audio_channel_mask = AUDIO_CHANNEL_IN_STEREO;
    mStreamAttributeTarget.num_channels = android_audio_legacy::AudioSystem::popCount(mStreamAttributeTarget.audio_channel_mask);
    mStreamAttributeTarget.sample_rate = ChooseTargetSampleRate(mStreamAttributeSource->sample_rate);
    // HW pcm config
    mConfig.channels = mStreamAttributeTarget.num_channels;
    mConfig.rate = mStreamAttributeTarget.sample_rate; 
    
    // Buffer size: 1536(period_size) * 2(ch) * 4(byte) * 2(period_count) = 24 kb

    mConfig.period_count = 2;
    mConfig.period_size = (mStreamAttributeTarget.buffer_size / (mConfig.channels * mConfig.period_count)) / ((mStreamAttributeTarget.audio_format == AUDIO_FORMAT_PCM_16_BIT) ? 2 : 4);

    mConfig.format = transferAudioFormatToPcmFormat(mStreamAttributeTarget.audio_format);

    mConfig.start_threshold = 0;
    mConfig.stop_threshold = 0;
    mConfig.silence_threshold = 0;
    ALOGD("%s(), mConfig: channels = %d, rate = %d, period_size = %d, period_count = %d, format = %d",
          __FUNCTION__, mConfig.channels, mConfig.rate, mConfig.period_size, mConfig.period_count, mConfig.format);

    mComprConfig.codec = (struct snd_codec*)malloc(sizeof(struct snd_codec));
    if(mComprConfig.codec == NULL)
        ALOGE("%s(), allocate mComprConfig.codec fail");
    mComprConfig.fragments = 1024;
    mComprConfig.fragment_size = 8192;
    //mComprConfig.fragment_size = mStreamAttributeTarget.buffer_size;
    mComprConfig.codec->sample_rate = mStreamAttributeTarget.sample_rate;
    mComprConfig.codec->reserved[0] = mConfig.period_size;
    mComprConfig.codec->reserved[1] = mComprConfig.fragments*mComprConfig.fragment_size;
    if(mConfig.format == PCM_FORMAT_S16_LE)
        mComprConfig.codec->format = SNDRV_PCM_FORMAT_S16_LE;
    else
        mComprConfig.codec->format = SNDRV_PCM_FORMAT_S32_LE;
    mComprConfig.codec->id = SND_AUDIOCODEC_MP3;
    mComprConfig.codec->ch_in = 2;
    mComprConfig.codec->ch_out = 2;
	

    //init decoder
    mDecHandler = AudioDecHandlerCreate();
    if(mDecHandler == NULL)
    {
        ALOGE("+%s(), DecHandler create fail", __FUNCTION__);
        ASSERT(false);
        return -ENOSYS;
    }
    if(!mDecHandler->InitAudioDecoder())
    {
        ALOGE("+%s(), Decoder IP init fail", __FUNCTION__);
        ASSERT(false);
        return -ENOSYS;
    }
    
    // post processing
    initPostProcessing();
       // SRC
    initBliSrc();

    // bit conversion
    initBitConverter();

    initDataPending();

    // disable lowjitter mode   //doug to check
    SetLowJitterMode(true, mStreamAttributeTarget.sample_rate);

    openComprDriver(23);

	if( compress_set_gapless_metadata(mComprStream, &offload_stream.offload_mdata) != 0)
        ALOGE("%s(), compress_set_gapless_metadata() error= %s", __FUNCTION__, compress_get_error(mComprStream));

    mHardwareResourceManager->startOutputDevice(mStreamAttributeSource->output_devices, mStreamAttributeTarget.sample_rate);

    offload_stream.tmpBuffer = (void*)malloc(mComprConfig.fragment_size);
	mWritebytes = mComprConfig.fragment_size;

	list_init(&offload_stream.offload_cmd_list);

    int ret = pthread_mutex_init(&offload_stream.offload_mutex, NULL);
    if (ret != 0)
    {
        ALOGE("%s, Failed to initialize Mutex!", __FUNCTION__);
        ASSERT(false);
        return -ENOSYS;
    }
	
    ret = pthread_cond_init(&offload_stream.offload_cond, NULL);
    if (ret != 0)
    {
        ALOGE("%s, Failed to initialize Cond!", __FUNCTION__);
        ASSERT(false);
        return -ENOSYS;
    }

	threadExit = false;
    ret = pthread_create(&offload_stream.offload_pthread, NULL, &offload_threadloop, this);

    if (ret != 0)
    {
        ALOGE("%s() create thread OffloadWrite fail!!", __FUNCTION__);
        ASSERT(false);
        return -ENOSYS;
    }

    usleep(1 * 1000);
	
    ALOGD("-%s()", __FUNCTION__);
    return NO_ERROR;
 
}
Пример #16
0
static int validate_input_hardware_params(struct stream_in *in)
{
    struct audio_device *adev = in->dev;
    struct pcm_params *params;
    unsigned int min;
    unsigned int max;

    params = pcm_params_get(adev->card, adev->device, PCM_IN);
    if (params == NULL) {
        ALOGW("Device does not exist.\n");
        return -1;
    }

    /* always open the device with min capabilities if
     * input params are not supported
     */

    min = pcm_params_get_min(params, PCM_PARAM_RATE);
    max = pcm_params_get_max(params, PCM_PARAM_RATE);
    ALOGI("hw supported Rate:\tmin=%uHz\tmax=%uHz\n", min, max);
    if((in->pcm_config.rate < min) || (in->pcm_config.rate > max)) {
       in->pcm_config.rate = min;
    }

    min = pcm_params_get_min(params, PCM_PARAM_CHANNELS);
    max = pcm_params_get_max(params, PCM_PARAM_CHANNELS);
    ALOGI("hw supported Channels:\tmin=%u\t\tmax=%u\n", min, max);
    if((in->pcm_config.channels < min) || (in->pcm_config.channels > max)) {
       in->pcm_config.channels = min;
    }

    min = pcm_params_get_min(params, PCM_PARAM_SAMPLE_BITS);
    max = pcm_params_get_max(params, PCM_PARAM_SAMPLE_BITS);
    ALOGI("hw supported Sample bits:\tmin=%u\t\tmax=%u\n", min, max);

    unsigned int bits_per_sample = format_to_bits(in->pcm_config.format);

    if((bits_per_sample < min) || (bits_per_sample > max)) {
       bits_per_sample = min;
    }

    in->pcm_config.format = bits_to_format(bits_per_sample);

    min = pcm_params_get_min(params, PCM_PARAM_PERIODS);
    max = pcm_params_get_max(params, PCM_PARAM_PERIODS);
    ALOGI("hw supported period_count:\tmin=%u\t\tmax=%u\n", min, max);
    if((in->pcm_config.period_count < min) || (in->pcm_config.period_count > max)) {
       in->pcm_config.period_count = min;
    }

    min = pcm_params_get_min(params, PCM_PARAM_PERIOD_SIZE);
    max = pcm_params_get_max(params, PCM_PARAM_PERIOD_SIZE);
    ALOGI("hw supported period_size:\tmin=%u\t\tmax=%u\n", min, max);
    if((in->pcm_config.period_size < min) || (in->pcm_config.period_size > max)) {
       in->pcm_config.period_size = min;
    }

    ALOGV("%s :: Exit supported params \
         \r \t channels = %d,    \
         \r \t rate     = %d,    \
         \r \t period_size = %d, \
         \r \t period_count = %d, \
         \r \t format = %d", __func__,
       in->pcm_config.channels,in->pcm_config.rate,
       in->pcm_config.period_size,in->pcm_config.period_count,
       in->pcm_config.format);

    pcm_params_free(params);

    return 0;

}