Exemple #1
0
audio_t *
audio_new(audio_config_t *cfg, audio_device_t *device)
{
    struct pcm_config config;
    struct pcm *pcm;
    audio_t *c;

    if (cfg->bits != 16 && cfg->bits != 24 && cfg->bits != 32) {
	errno = EINVAL;
	return NULL;
    }

    config.channels = cfg->channels;
    config.rate = cfg->rate;
    config.period_size = 1024;
    config.period_count = 4;
    config.format = cfg->bits == 16 ? PCM_FORMAT_S16_LE : cfg->bits == 32 ? PCM_FORMAT_S32_LE : PCM_FORMAT_S24_LE;
    config.start_threshold = config.stop_threshold = config.silence_threshold = 0;

    if ((pcm = pcm_open(device->card, device->device, device->playback ? PCM_OUT : PCM_IN, &config)) == NULL ||
	! pcm_is_ready(pcm))
    {
	fprintf(stderr, "Failed to open: %s\n", pcm_get_error(pcm));
	return NULL;
    }

    c = fatal_malloc(sizeof(*c));
    c->pcm = pcm;
    c->cfg = *cfg;
    c->dev = *device;
    c->buffer_size = pcm_frames_to_bytes(pcm, pcm_get_buffer_size(pcm));

    return c;
}
static int hdmi_out_open_pcm(hdmi_out_t *out)
{
    int card = hdmi_out_find_card();
    int dev = HDMI_PCM_DEV;
    int ret;

    TRACEM("out=%p", out);

    /* out->up must be 0 (down) */
    if (out->up) {
        ALOGE("Trying to open a PCM that's already up. "
             "This will probably deadlock... so aborting");
        return 0;
    }

    out->pcm = pcm_open(card, dev, PCM_OUT, &out->config);

    if(out->pcm && pcm_is_ready(out->pcm)) {
        out->up = 1;
        ret = 0;
    } else {
        ALOGE("cannot open HDMI pcm card %d dev %d error: %s",
              card, dev, pcm_get_error(out->pcm));
        pcm_close(out->pcm);
        out->pcm = 0;
        out->up = 0;
        ret = 1;
    }

    return ret;
}
bool AudioRecordingLocal::doPrepare(AudioHardware::SamplingRate samplingRate, int samplesInOneGo)
{
    releaseHw();

    struct pcm_config config;

    memset(&config, 0, sizeof(config));
    config.channels = 2;
    config.rate = samplingRate;
    config.period_size = 1024;
    config.period_count = 32;
    config.format = PCM_FORMAT_S16_LE;
    config.start_threshold = 0;
    config.stop_threshold = 0;
    config.silence_threshold = 0;

    mPcmHandle = pcm_open(mHwId, 0, PCM_IN, &config);
    if (!mPcmHandle || !pcm_is_ready(mPcmHandle)) {
       LOGE("Unable to open PCM device(%d) (%s)\n", mHwId, pcm_get_error(mPcmHandle));
       return false;
    }

    mSamples = samplesInOneGo;
    mSizes = samplesInOneGo * 4; // stereo, 16bit

    mBufferSize = pcm_get_buffer_size(mPcmHandle);
    LOGD("buffer size %d, read size %d", mBufferSize, mSizes);
    return true;
}
Exemple #4
0
status_t AudioALSACaptureDataProviderBase::openPcmDriver(const unsigned int device)
{
    ALOGD("+%s(), pcm device = %d", __FUNCTION__, device);

    ASSERT(mPcm == NULL);
    mPcm = pcm_open(kAudioSoundCardIndex, device, PCM_IN, &mConfig);
    if (mPcm == NULL)
    {
        ALOGE("%s(), mPcm == NULL!!", __FUNCTION__);
    }
    else if (pcm_is_ready(mPcm) == false)
    {
        ALOGE("%s(), pcm_is_ready(%p) == false due to %s, close pcm.", __FUNCTION__, mPcm, pcm_get_error(mPcm));
        pcm_close(mPcm);
        mPcm = NULL;
    }
    else
    {
        pcm_start(mPcm);
    }

    ALOGD("-%s(), mPcm = %p", __FUNCTION__, mPcm);
    ASSERT(mPcm != NULL);
    return NO_ERROR;
}
int proxy_open(alsa_device_proxy * proxy)
{
    alsa_device_profile* profile = proxy->profile;
    ALOGV("proxy_open(card:%d device:%d %s)", profile->card, profile->device,
          profile->direction == PCM_OUT ? "PCM_OUT" : "PCM_IN");

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

    proxy->pcm = pcm_open(profile->card, profile->device,
            profile->direction | PCM_MONOTONIC, &proxy->alsa_config);
    if (proxy->pcm == NULL) {
        return -ENOMEM;
    }

    if (!pcm_is_ready(proxy->pcm)) {
        ALOGE("  proxy_open() pcm_open() failed: %s", pcm_get_error(proxy->pcm));
#if defined(LOG_PCM_PARAMS)
        log_pcm_config(&proxy->alsa_config, "config");
#endif
        pcm_close(proxy->pcm);
        proxy->pcm = NULL;
        return -ENOMEM;
    }

    return 0;
}
bool TinyAlsaCtlPortConfig::doOpenStream(StreamDirection streamDirection, std::string &error)
{
    struct pcm *&streamHandle = _streamHandle[streamDirection];
    struct pcm_config pcmConfig;

    const AlsaCtlPortConfig::PortConfig &portConfig = getPortConfig();

    // Fill PCM configuration structure
    pcmConfig.channels = portConfig.channelNumber;
    pcmConfig.rate = portConfig.sampleRate;

    // Check Format is supported by the plugin
    if (portConfig.format >= pcmFormatTranslationTableSize) {

        error = "The format n°" + asString(portConfig.format) +
                " is not supported by the TinyAlsa plugin";
        return false;
    }

    uint8_t format = pcmFormatTranslationTable[portConfig.format].formatAsNumerical;

    // Check format is supported by Tinyalsa
    if (format == std::numeric_limits<uint8_t>::max()) {

        error = "The format " + pcmFormatTranslationTable[portConfig.format].formatAsString +
                " is not supported by Tinyalsa";
        return false;
    }

    pcmConfig.format = static_cast<pcm_format>(format);

    pcmConfig.period_size       = _periodTimeMs * pcmConfig.rate / _msPerSec;
    pcmConfig.period_count      = _nbRingBuffer;
    pcmConfig.start_threshold   = 0;
    pcmConfig.stop_threshold    = 0;
    pcmConfig.silence_threshold = 0;
    pcmConfig.silence_size      = 0;
    pcmConfig.avail_min         = 0;

    // Open and configure
    streamHandle = pcm_open(getCardNumber(),
                            getDeviceNumber(),
                            streamDirection == Capture ? PCM_IN : PCM_OUT,
                            &pcmConfig);

    // Prepare the stream
    if (!pcm_is_ready(streamHandle) || (pcm_prepare(streamHandle) != 0)) {

        // Format error
        error = formatAlsaError(streamDirection, "open", pcm_get_error(streamHandle));

        doCloseStream(streamDirection);
        return false;
    }

    return true;
}
Exemple #7
0
static size_t read_frames(void **frames)
{
    unsigned int card = 0;
    unsigned int device = 0;
    int flags = PCM_IN;

    const struct pcm_config config = {
        .channels = 2,
        .rate = 48000,
        .format = PCM_FORMAT_S32_LE,
        .period_size = 1024,
        .period_count = 2,
        .start_threshold = 1024,
        .silence_threshold = 1024 * 2,
        .stop_threshold = 1024 * 2
    };

    struct pcm *pcm = pcm_open(card, device, flags, &config);
    if (pcm == NULL) {
        fprintf(stderr, "failed to allocate memory for PCM\n");
        return EXIT_FAILURE;
    } else if (!pcm_is_ready(pcm)){
        pcm_close(pcm);
        fprintf(stderr, "failed to open PCM\n");
        return EXIT_FAILURE;
    }

    unsigned int frame_size = pcm_frames_to_bytes(pcm, 1);
    unsigned int frames_per_sec = pcm_get_rate(pcm);

    *frames = malloc(frame_size * frames_per_sec);
    if (*frames == NULL) {
        fprintf(stderr, "failed to allocate frames\n");
        pcm_close(pcm);
        return EXIT_FAILURE;
    }

    int read_count = pcm_readi(pcm, *frames, frames_per_sec);

    size_t byte_count = pcm_frames_to_bytes(pcm, read_count);

    pcm_close(pcm);

    return byte_count;
}

static int write_file(const void *frames, size_t size)
{
    FILE *output_file = fopen("audio.raw", "wb");
    if (output_file == NULL) {
        perror("failed to open 'audio.raw' for writing");
        return EXIT_FAILURE;
    }
    fwrite(frames, 1, size, output_file);
    fclose(output_file);
    return 0;
}
void play_sample(FILE *file, unsigned int device, unsigned int channels,
                 unsigned int rate, unsigned int bits)
{
    struct pcm_config config;
    struct pcm *pcm0;
    char *buffer;
    int size;
    int num_read;
/*
channels = 2,period_size = 8092;  buffer_size = 8092*4 = 32k
channels = 4, period_size = 4096, buffer_size = 4096*8 = 32k
channels = 4, period_size = 2048, buffer_size = 2048*8 = 16k
channels = 4, period_size = 1024, buffer_size = 1024*8 = 8k
*/
    config.channels = 4;
    config.rate = rate;
    config.period_size = 1024;//4096;//2048
    config.period_count = 1;
    if (bits == 32)
        config.format = PCM_FORMAT_S32_LE;
    else if (bits == 16)
        config.format = PCM_FORMAT_S16_LE;
    config.start_threshold = 0;
    config.stop_threshold = 0;
    config.silence_threshold = 0;

	/*0 is audiocodec, 1 is hdmiaudio, 2 is spdif*/
    pcm0 = pcm_open(1, device, PCM_OUT, &config);
    if (!pcm0 || !pcm_is_ready(pcm0)) {
		fprintf(stderr, "Unable to open PCM device %u (%s)\n", device, pcm_get_error(pcm0));
		return;
	}

    size = pcm_get_buffer_size(pcm0);
    buffer = malloc(size);
    if (!buffer) {
        fprintf(stderr, "Unable to allocate %d bytes\n", size);
        free(buffer);
        pcm_close(pcm0);
        return;
    }
    size =size;
    printf("hx-Playing sample:size:%d, %u ch, %u hz, %u bit\n", size, channels, rate, bits);

    do {
        num_read = fread(buffer, 1, size, file);
        if (num_read > 0) {
            if (pcm_write(pcm0, buffer, num_read)) {
                fprintf(stderr, "Error playing sample\n");
                break;
            }
        }
    } while (num_read > 0);

    free(buffer);
    pcm_close(pcm0);
}
Exemple #9
0
static int write_frames(const void * frames, size_t byte_count){

    unsigned int card = 0;
    unsigned int device = 0;
    int flags = PCM_OUT;

    const struct pcm_config config = {
        .channels = 2,
        .rate = 48000,
        .format = PCM_FORMAT_S32_LE,
        .period_size = 1024,
        .period_count = 2,
        .start_threshold = 1024,
        .silence_threshold = 1024 * 2,
        .stop_threshold = 1024 * 2
    };

    struct pcm * pcm = pcm_open(card, device, flags, &config);
    if (pcm == NULL) {
        fprintf(stderr, "failed to allocate memory for PCM\n");
        return -1;
    } else if (!pcm_is_ready(pcm)){
        pcm_close(pcm);
        fprintf(stderr, "failed to open PCM\n");
        return -1;
    }

    unsigned int frame_count = pcm_bytes_to_frames(pcm, byte_count);

    int err = pcm_writei(pcm, frames, frame_count);
    if (err != 0) {
      printf("error: %s\n", pcm_get_error(pcm));
    }

    pcm_close(pcm);

    return 0;
}

int main(void)
{
    void *frames;
    size_t size;

    size = read_file(&frames);
    if (size == 0) {
        return EXIT_FAILURE;
    }

    if (write_frames(frames, size) < 0) {
        return EXIT_FAILURE;
    }

    free(frames);
    return EXIT_SUCCESS;
}
status_t AudioALSACaptureDataProviderBTSCO::open()
{
    ALOGD("%s()", __FUNCTION__);
    ASSERT(mClientLock.tryLock() != 0); // lock by base class attach
    AudioAutoTimeoutLock _l(mEnableLock);

    ASSERT(mEnable == false);

    // config attribute (will used in client SRC/Enh/... later) // TODO(Harvey): query this
    mStreamAttributeSource.audio_format = AUDIO_FORMAT_PCM_16_BIT;
    mStreamAttributeSource.audio_channel_mask = AUDIO_CHANNEL_IN_MONO;
    mStreamAttributeSource.num_channels = android_audio_legacy::AudioSystem::popCount(mStreamAttributeSource.audio_channel_mask);
    mStreamAttributeSource.sample_rate = mWCNChipController->GetBTCurrentSamplingRateNumber();


    // pcm config
    mConfig.channels = mStreamAttributeSource.num_channels;
    mConfig.rate = mStreamAttributeSource.sample_rate;

    // Buffer size: 2048(period_size) * 1(ch) * 2(byte) * 4(period_count) = 16 kb
    mConfig.period_size = 2048;
    mConfig.period_count = 4;
    mConfig.format = PCM_FORMAT_S16_LE;

    mConfig.start_threshold = 0;
    mConfig.stop_threshold = 0;
    mConfig.silence_threshold = 0;

    ALOGD("%s(), audio_format = %d, audio_channel_mask=%x, num_channels=%d, sample_rate=%d", __FUNCTION__,
          mStreamAttributeSource.audio_format, mStreamAttributeSource.audio_channel_mask, mStreamAttributeSource.num_channels, mStreamAttributeSource.sample_rate);

    ALOGD("%s(), format = %d, channels=%d, rate=%d", __FUNCTION__,
          mConfig.format, mConfig.channels, mConfig.rate);

    OpenPCMDump(LOG_TAG);

    // enable pcm
    ASSERT(mPcm == NULL);
    mPcm = pcm_open(0, 12, PCM_IN | PCM_MONOTONIC, &mConfig);
    ASSERT(mPcm != NULL && pcm_is_ready(mPcm) == true);
    ALOGV("%s(), mPcm = %p", __FUNCTION__, mPcm);

    pcm_start(mPcm);

    // create reading thread
    mEnable = true;
    int ret = pthread_create(&hReadThread, NULL, AudioALSACaptureDataProviderBTSCO::readThread, (void *)this);
    if (ret != 0)
    {
        ALOGE("%s() create thread fail!!", __FUNCTION__);
        return UNKNOWN_ERROR;
    }

    return NO_ERROR;
}
Exemple #11
0
unsigned int capture_sample(FILE *file, unsigned int card, unsigned int device,
                            unsigned int channels, unsigned int rate,
                            enum pcm_format format, unsigned int period_size,
                            unsigned int period_count)
{
    struct pcm_config config;
    struct pcm *pcm;
    char *buffer;
    unsigned int size;
    unsigned int bytes_read = 0;

    memset(&config, 0, sizeof(config));
    config.channels = channels;
    config.rate = rate;
    config.period_size = period_size;
    config.period_count = period_count;
    config.format = format;
    config.start_threshold = 0;
    config.stop_threshold = 0;
    config.silence_threshold = 0;

    pcm = pcm_open(card, device, PCM_IN, &config);
    if (!pcm || !pcm_is_ready(pcm)) {
        fprintf(stderr, "Unable to open PCM device (%s)\n",
                pcm_get_error(pcm));
        return 0;
    }

    size = pcm_frames_to_bytes(pcm, pcm_get_buffer_size(pcm));
    buffer = malloc(size);
    if (!buffer) {
        fprintf(stderr, "Unable to allocate %d bytes\n", size);
        free(buffer);
        pcm_close(pcm);
        return 0;
    }

    printf("Capturing sample: %u ch, %u hz, %u bit\n", channels, rate,
           pcm_format_to_bits(format));

    while (capturing && !pcm_read(pcm, buffer, size)) {
        if (fwrite(buffer, 1, size, file) != size) {
            fprintf(stderr,"Error capturing sample\n");
            break;
        }
        bytes_read += size;
    }

    free(buffer);
    pcm_close(pcm);
    return pcm_bytes_to_frames(pcm, bytes_read);
}
Exemple #12
0
unsigned int capture_sample(FILE *file, unsigned int device,
                            unsigned int channels, unsigned int rate,
                            unsigned int bits)
{
    struct pcm_config config;
    struct pcm *pcm;
    char *buffer;
    unsigned int size;
    unsigned int bytes_read = 0;

    config.channels = channels;
    config.rate = rate;
    config.period_size = 1024;
    config.period_count = 4;
    if (bits == 32)
        config.format = PCM_FORMAT_S32_LE;
    else if (bits == 16)
        config.format = PCM_FORMAT_S16_LE;

    pcm = pcm_open(0, device, PCM_IN, &config);
    if (!pcm || !pcm_is_ready(pcm)) {
        fprintf(stderr, "Unable to open PCM device (%s)\n",
                pcm_get_error(pcm));
        return 0;
    }

    size = pcm_get_buffer_size(pcm);
    buffer = malloc(size);
    if (!buffer) {
        fprintf(stderr, "Unable to allocate %d bytes\n", size);
        free(buffer);
        pcm_close(pcm);
        return 0;
    }

    printf("Capturing sample: %u ch, %u hz, %u bit\n", channels, rate, bits);

    while (capturing && !pcm_read(pcm, buffer, size)) {
        if (fwrite(buffer, 1, size, file) != size) {
            fprintf(stderr,"Error capturing sample\n");
            break;
        }
        bytes_read += size;
    }

    free(buffer);
    pcm_close(pcm);
    return bytes_read / ((bits / 8) * channels);
}
Exemple #13
0
static int inner_main(struct tone_generator_config config)
{
	struct pcm_config *pcm_config = &config.pcm_config;
	struct pcm *pcm;
	unsigned pos;
	void *buf;

	pcm = pcm_open(config.card, config.device, PCM_OUT, pcm_config);
	if (!pcm) {
		fprintf(stderr, "Could not open sound card\n");
		fprintf(stderr, "%s\n", pcm_get_error(pcm));
		return 1;
	}
	if (!pcm_is_ready(pcm)) {
		fprintf(stderr, "Sound card not ready\n");
		fprintf(stderr, "%s\n", pcm_get_error(pcm));
		return 1;
	}

	buf = calloc(config.bits / 8,
			pcm_config->period_size * pcm_config->channels);
	if (!buf) {
		fprintf(stderr, "Could not allocate memory for buffer\n");
		return 1;
	}

	for (pos=0 ; (!config.duration || (pos < config.duration)) ; pos += pcm_config->period_size) {
		oscillator_table_render(buf,
			config.wave_table,
			pos,
			pcm_config->period_size,
			config.wave_scale,
			pcm_config->channels,
			config.chan_mask, /* write to all channels */
			config.volume,
			config.bits);
		if (pcm_write(pcm,
			      buf,
			      pcm_config->channels * pcm_config->period_size * (config.bits/8))) {
			fprintf(stderr, "Error writing to sound card\n");
			fprintf(stderr, "%s\n", pcm_get_error(pcm));
		}
	}

	pcm_close(pcm);

	return 0;
}
static bool profile_test_sample_rate(alsa_device_profile* profile, unsigned rate)
{
    struct pcm_config config = profile->default_config;
    config.rate = rate;

    bool works = false; /* let's be pessimistic */
    struct pcm * pcm = pcm_open(profile->card, profile->device,
                                profile->direction, &config);

    if (pcm != NULL) {
        works = pcm_is_ready(pcm);
        pcm_close(pcm);
    }

    return works;
}
Exemple #15
0
EXTERN_TAG int  pcm_output_init(int sr,int ch)
{
    int card = 0;
    int device = 2;
    cached_len = 0;
    wfd_config_out.channels = 2;
    wfd_config_out.rate = 48000;
    wfd_config_out.period_size = WFD_PERIOD_SIZE;
    wfd_config_out.period_count = WFD_PERIOD_NUM;
    wfd_config_out.format = PCM_FORMAT_S16_LE;
    wfd_config_out.start_threshold = WFD_PERIOD_SIZE;
    wfd_config_out.avail_min = 0;//SHORT_PERIOD_SIZE;
    card = get_aml_card();
    if(card  < 0)
    {
    	card = 0;
	adec_print("get aml card fail, use default \n");
    }
	// if hdmi state on 
	if(get_hdmi_switch_state())
		device = get_spdif_port();
	else
		device = 0; //i2s output for analog output
    if(device < 0)
    {
    	device = 0;
	adec_print("get aml card device fail, use default \n");
    }
    adec_print("open output device card %d, device %d \n",card,device);	
    if(sr < 32000|| sr > 48000 || ch != 2){
		adec_print("wfd output: not right parameter sr %d,ch %d \n",sr,ch);
		return -1;
    }
    wfd_config_out.rate = sr;
    wfd_config_out.channels = ch;
    wfd_pcm = pcm_open(card, device, PCM_OUT /*| PCM_MMAP | PCM_NOIRQ*/, &wfd_config_out);
    if (!pcm_is_ready(wfd_pcm)) {
        adec_print("wfd cannot open pcm_out driver: %s", pcm_get_error(wfd_pcm));		
        pcm_close(wfd_pcm);
	 return -1;	
    }
    adec_print("pcm_output_init done  wfd : %p,\n",wfd_pcm);
    return 0;	
   
}
Exemple #16
0
/* must be called with hw device and output stream mutexes locked */
static int start_output_stream(struct stream_out *out)
{
    struct audio_device *adev = out->dev;
    int i;

    if ((adev->card < 0) || (adev->device < 0))
        return -EINVAL;

    out->pcm = pcm_open(adev->card, adev->device, PCM_OUT, &pcm_config);

    if (out->pcm && !pcm_is_ready(out->pcm)) {
        ALOGE("pcm_open() failed: %s", pcm_get_error(out->pcm));
        pcm_close(out->pcm);
        return -ENOMEM;
    }

    return 0;
}
Exemple #17
0
int InStream::startInputStream() {
    LOGFUNC("%s(%p)", __func__, this);

    mUcm.activateEntry(mEntry, this);
    int card = mUcm.getCaptureCard(mEntry);
    int port = mUcm.getCapturePort(mEntry);

    ALOGE("setting capture card=%d port=%d", card, port);

    mPcm = pcm_open(card, port, PCM_IN, &mConfig);
    if (!pcm_is_ready(mPcm)) {
        ALOGE("cannot open pcm_in driver: %s", pcm_get_error(mPcm));
        pcm_close(mPcm);
        mPcm = NULL;
		mUcm.deactivateEntry(mEntry);
        return -ENOMEM;
    }
    mStandby = false;
    return 0;
}
bool SpeechANCController::StartPCMIn(char mTypePCM, uint32_t device, pcm_config mConfig)
{
    ALOGD("+%s(), pcm device = %d", __FUNCTION__, device);
    pcm *mPcm;

    //ASSERT(mPcm == NULL);
    mPcm = pcm_open(kAudioSoundCardIndex, device, PCM_IN, &mConfig);
    if (mPcm == NULL)
    {
        ALOGE("%s(), mPcm == NULL!!", __FUNCTION__);
    }
    else if (pcm_is_ready(mPcm) == false)
    {
        ALOGE("%s(), pcm_is_ready(%p) == false due to %s, close pcm.", __FUNCTION__, mPcm, pcm_get_error(mPcm));
        pcm_close(mPcm);
        mPcm = NULL;
    }
    else
    {
        pcm_start(mPcm);
    }

    ALOGD("-%s(), mPcm = %p", __FUNCTION__, mPcm);
    ASSERT(mPcm != NULL);

    switch (mTypePCM)
    {
        case 0:
            mPcmIn_MOD = mPcm ;
            break;
        case 1:
            mPcmIn_IO2 = mPcm;
            break;
        case 2:
            mPcmIn_ADC2 = mPcm;
            break;
    }

    return true;

}
int start_input_stream(struct stream_in *in)
{
    int ret = 0;
    struct audio_device *adev = in->dev;

    adev->card = get_card_number_by_name("USB Audio");
    adev->device = DEFAULT_DEVICE;
    ALOGVV("%s: USB card number = %d, device = %d",__func__,adev->card,adev->device);

    ALOGV("%s :: requested 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);

    ret = validate_input_hardware_params(in);
    if(ret != 0) {
        ALOGE("Unsupport input stream parameters");
        in->pcm = NULL;
        return -ENOSYS;
    }

    in->pcm = pcm_open(adev->card, adev->device,
                           PCM_IN, &in->pcm_config);
    if (in->pcm && !pcm_is_ready(in->pcm)) {
        ALOGE("%s: %s", __func__, pcm_get_error(in->pcm));
        pcm_close(in->pcm);
        in->pcm = NULL;
        ret = -EIO;
        ALOGD("%s: exit: status(%d)", __func__, ret);
        return ret;
    } else {
        ALOGV("%s: exit capture pcm = %x", __func__,in->pcm);
        return ret;
    }
}
status_t AudioALSACaptureDataProviderTDM::open()
{
    ALOGD("%s()", __FUNCTION__);
    ASSERT(mClientLock.tryLock() != 0); // lock by base class attach
    AudioAutoTimeoutLock _l(mEnableLock);
    AudioAutoTimeoutLock _l2(*AudioALSADriverUtility::getInstance()->getStreamSramDramLock());

    ASSERT(mEnable == false);

    // config attribute (will used in client SRC/Enh/... later) // TODO(Harvey): query this
    mStreamAttributeSource.audio_format = AUDIO_FORMAT_PCM_16_BIT;
    mStreamAttributeSource.audio_channel_mask = AUDIO_CHANNEL_IN_STEREO;
    mStreamAttributeSource.num_channels = android_audio_legacy::AudioSystem::popCount(mStreamAttributeSource.audio_channel_mask);
    mStreamAttributeSource.sample_rate = 44100;

    OpenPCMDump(LOG_TAG);

    // enable pcm
    ASSERT(mPcm == NULL);
    mPcm = pcm_open(0, 13, PCM_IN, &mConfig);
    //    mPcm = pcm_open(0, 1, PCM_IN, &mConfig);

    ASSERT(mPcm != NULL && pcm_is_ready(mPcm) == true);
    ALOGV("%s(), mPcm = %p", __FUNCTION__, mPcm);

    pcm_start(mPcm);

    // create reading thread
    mEnable = true;
    int ret = pthread_create(&hReadThread, NULL, AudioALSACaptureDataProviderTDM::readThread, (void *)this);
    if (ret != 0)
    {
        ALOGE("%s() create thread fail!!", __FUNCTION__);
        return UNKNOWN_ERROR;
    }

    return NO_ERROR;
}
int muroard_driver_init(const char * dev) {
 struct pcm_config config;
 unsigned int period_size = muroard_state_member(abuffer_size);
 unsigned int period_count = 4;
 unsigned int card = 0;
 unsigned int device = 0;

 config.channels = muroard_state_member(sa_channels);
 config.rate = muroard_state_member(sa_rate);
 config.format = PCM_FORMAT_S16_LE;
 config.start_threshold = 0;
 config.stop_threshold = 0;
 config.silence_threshold = 0;
 config.period_size = period_size;
 config.period_count = period_count;


 muroard_state_member(driver_vp) = pcm_open(card, device, PCM_OUT, &config);
 if (!muroard_state_member(driver_vp) || !pcm_is_ready(muroard_state_member(driver_vp)))
  return -1;

 return 0;
}
static int initialize_device(out123_handle *ao)
{
	mpg123_tinyalsa_t* ta = (mpg123_tinyalsa_t*)ao->userptr;

	ta->config.channels = ao->channels;
	ta->config.rate = ao->rate;
    	ta->config.period_size = 1024;
    	ta->config.period_count = 4;
       	ta->config.format = PCM_FORMAT_S16_LE;
    	ta->config.start_threshold = 0;
    	ta->config.stop_threshold = 0;
	ta->config.silence_threshold = 0;

	ta->pcm = pcm_open(ta->card, ta->device, PCM_OUT, &ta->config);
	if (!ta->pcm || !pcm_is_ready(ta->pcm))
	{
		if(!AOQUIET)
			error3( "(open) Unable to open card %u PCM device %u (%s)\n"
			,	ta->card, ta->device, pcm_get_error(ta->pcm) );
		return -1;
	}

	return 0;
}
status_t AudioALSAFMController::setFmDirectConnection(const bool enable, const bool bforce)
{
    ALOGD("+%s(), enable = %d, bforce = %d", __FUNCTION__, enable, bforce);

    // Check Current Status
    if (mIsFmDirectConnectionMode == enable && bforce == false)
    {
        ALOGW("-%s(), enable = %d, bforce = %d", __FUNCTION__, enable, bforce);
        return INVALID_OPERATION;
    }


    // Apply
    if (enable == true)
    {
        mConfig.channels = 2;
        mConfig.rate = getFmDownlinkSamplingRate();
        mConfig.period_size = 3072;
        mConfig.period_count = 2;
        mConfig.format = PCM_FORMAT_S16_LE;
        mConfig.start_threshold = 0;
        mConfig.stop_threshold = 0;
        mConfig.silence_threshold = 0;

        if (mPcm == NULL)
        {
            // Get pcm open Info
            int card_index = -1;
            int pcm_index = -1;
            if (WCNChipController::GetInstance()->IsFMMergeInterfaceSupported() == true)
            {
                card_index = AudioALSADeviceParser::getInstance()->GetCardIndexByString(keypcmMRGrxPlayback);
                pcm_index = AudioALSADeviceParser::getInstance()->GetPcmIndexByString(keypcmMRGrxPlayback);
            }
            else
            {
                card_index = AudioALSADeviceParser::getInstance()->GetCardIndexByString(keypcmFMI2SPlayback);
                pcm_index = AudioALSADeviceParser::getInstance()->GetPcmIndexByString(keypcmFMI2SPlayback);
            }
            ALOGD("%s(), card_index = %d, pcm_index = %d", __FUNCTION__, card_index, pcm_index);

            mPcm = pcm_open(card_index, pcm_index , PCM_OUT, &mConfig);
            ALOGD("%s(), pcm_open mPcm = %p", __FUNCTION__, mPcm);
        }
        if (mPcm == NULL || pcm_is_ready(mPcm) == false)
        {
            ALOGE("%s(), Unable to open mPcm device %u (%s)", __FUNCTION__, 6 , pcm_get_error(mPcm));
        }
        pcm_start(mPcm);
    }
    else
    {
        if (mPcm != NULL)
        {
            pcm_stop(mPcm);
            pcm_close(mPcm);
            mPcm = NULL;
        }
    }


    // Update Direct Mode Status
    mIsFmDirectConnectionMode = enable;

    // Update (HW_GAIN2) Volume for Direct Mode Only
    if (mIsFmDirectConnectionMode == true)
    {
        setFmVolume(mFmVolume);
    }


    ALOGD("-%s(), enable = %d, bforce = %d", __FUNCTION__, enable, bforce);
    return NO_ERROR;
}
static int start_output_stream(struct stream_out *out)
{
    struct audio_device *adev = out->dev;
    int ret = 0;

    ALOGV("%s enter input 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);

    out->pcm_config.start_threshold = 0;
    out->pcm_config.stop_threshold = 0;
    out->pcm_config.silence_threshold = 0;

    // close the active device and make HD device active
    if(out->flags & AUDIO_OUTPUT_FLAG_DIRECT) {
        ALOGV("direct flag active stream");
        if(adev->active_pcm) {
          ALOGVV("Current active stream is closed to open HD interface %d",(int)adev->active_pcm);
          pcm_close(adev->active_pcm);
        }
        adev->hdaudio_active = true;
        adev->active_pcm = NULL;
    }

    // if HD device is active, use the same for subsequent streams
    if((adev->active_pcm) && (adev->hdaudio_active)) {
       out->pcm = adev->active_pcm;
       ALOGV("USB PCM interface already opened - use same params to render till its closed");
       goto skip_open;
    }

    /*TODO - this needs to be updated once the device connect intent sends
      card, device id*/
    adev->card = get_card_number_by_name("USB Audio");
    adev->device = DEFAULT_DEVICE;
    ALOGD("%s: USB card number = %d, device = %d",__func__,adev->card,adev->device);

    /* query & validate sink supported params and input params*/
    ret = validate_output_hardware_params(out);
    if(ret != 0) {
        ALOGE("Unsupport input stream parameters");
        adev->active_pcm = NULL;
        adev->hdaudio_active = false;
        out->pcm = NULL;
        return -ENOSYS;
    }

    out->pcm = pcm_open(adev->card, adev->device, PCM_OUT, &out->pcm_config);

    if (out->pcm && !pcm_is_ready(out->pcm)) {
        ALOGE("pcm_open() failed: %s", pcm_get_error(out->pcm));
        pcm_close(out->pcm);
        adev->active_pcm = NULL;
        adev->hdaudio_active = false;
        out->pcm = NULL;
        return -ENOSYS;
    }

    //update the newly opened pcm to be active
    adev->active_pcm = out->pcm;

skip_open:
    ALOGV("Initialized PCM device for channels %d sample rate %d activepcm = %d",
               out->pcm_config.channels,out->pcm_config.rate,(int)adev->active_pcm);
    ALOGV("%s exit",__func__);
    return 0;
}
Exemple #25
0
status_t AudioALSACaptureDataProviderEchoRefExt::open()
{
    ALOGD("%s()", __FUNCTION__);
    ASSERT(mClientLock.tryLock() != 0); // lock by base class attach
    AudioAutoTimeoutLock _l(mEnableLock);
    AudioAutoTimeoutLock _l2(*AudioALSADriverUtility::getInstance()->getStreamSramDramLock());

    ASSERT(mEnable == false);

    AudioALSASampleRateController *pAudioALSASampleRateController = AudioALSASampleRateController::getInstance();
    pAudioALSASampleRateController->setScenarioStatus(PLAYBACK_SCENARIO_ECHO_REF_EXT);

    // config attribute (will used in client SRC/Enh/... later) // TODO(Sam): query the mConfig?
    mStreamAttributeSource.audio_format = AUDIO_FORMAT_PCM_16_BIT;
    mStreamAttributeSource.audio_channel_mask = AUDIO_CHANNEL_IN_STEREO;
    mStreamAttributeSource.num_channels = android_audio_legacy::AudioSystem::popCount(mStreamAttributeSource.audio_channel_mask);
    mStreamAttributeSource.sample_rate = AudioALSASampleRateController::getInstance()->getPrimaryStreamOutSampleRate();


    mConfig.channels = mStreamAttributeSource.num_channels;
    mConfig.rate = mStreamAttributeSource.sample_rate;

    // Buffer size: 2048(period_size) * 2(ch) * 2(byte) * 8(period_count) = 64 kb
    mConfig.period_size = 2048;
    mConfig.period_count = 8;
    mConfig.format = PCM_FORMAT_S16_LE;

    mConfig.start_threshold = 0;
    mConfig.stop_threshold = 0;
    mConfig.silence_threshold = 0;


#if 0
    //latency time, set as DataProvider buffer size
    mStreamAttributeSource.latency = (kReadBufferSize * 1000) / (mStreamAttributeSource.num_channels * mStreamAttributeSource.sample_rate *
                                                                 (mStreamAttributeSource.audio_format == AUDIO_FORMAT_PCM_8_BIT ? 1 :    //8  1byte/frame
                                                                  (mStreamAttributeSource.audio_format == AUDIO_FORMAT_PCM_32_BIT ? 4 :   //24bit 3bytes/frame
                                                                   2)));   //default 2bytes/sample
#else
    //latency time, set as hardware buffer size
    mStreamAttributeSource.latency = (mConfig.period_size * mConfig.period_count * 1000) / mConfig.rate;
#endif

    ALOGD("%s(), audio_format = %d, audio_channel_mask=%x, num_channels=%d, sample_rate=%d, latency=%dms", __FUNCTION__,
          mStreamAttributeSource.audio_format, mStreamAttributeSource.audio_channel_mask, mStreamAttributeSource.num_channels, mStreamAttributeSource.sample_rate, mStreamAttributeSource.latency);

    ALOGD("%s(), format = %d, channels=%d, rate=%d", __FUNCTION__,
          mConfig.format, mConfig.channels, mConfig.rate);


#ifdef NXP_SMARTPA_SUPPORT
    MTK_Tfa98xx_EchoReferenceConfigure(1);
#endif

    OpenPCMDump(LOG_TAG);

    // enable pcm
    ASSERT(mPcm == NULL);
    mPcm = pcm_open(0, 16, PCM_IN | PCM_MONOTONIC, &mConfig);
    ASSERT(mPcm != NULL && pcm_is_ready(mPcm) == true);

    pcm_start(mPcm);

    // create reading thread
    mEnable = true;
    int ret = pthread_create(&hReadThread, NULL, AudioALSACaptureDataProviderEchoRefExt::readThread, (void *)this);
    if (ret != 0)
    {
        ALOGE("%s() create thread fail!!", __FUNCTION__);
        return UNKNOWN_ERROR;
    }

    return NO_ERROR;
}
int play(int argc, char **argv) {
    int nMixer = -1, nDevice = -1;

    pcm_config cfg = {
        channels : 0,
        rate : 0,
        period_size : 1024,
        period_count : 4,
        format : PCM_FORMAT_S16_LE,
        start_threshold : 0,
        stop_threshold : 0,
        silence_threshold : 0,
    };

    if (argc == 6) {
        nMixer = atoi(argv[2]);
        nDevice = atoi(argv[3]);
        cfg.rate = atoi(argv[4]);
        cfg.channels = atoi(argv[5]);
    }

    if (argc != 6 || nMixer < 0 || nMixer > 7 || nDevice < 0 || 
            cfg.rate <= 0 || cfg.channels <= 0 || cfg.channels > 2) {
        printf("Usage: ainfo play <card number> <device number> <rate> <channels>\n"
               "where <card number> is between 0 and 7\n"
               "<device number> is the device to play on\n"
               "<rate> is the sampling rate\n"
               "<channels> is either 1 or 2\n"
               "NOTE The file to be played is read from stdin\n");
        return 0;
    }

    pcm *p = pcm_open(nMixer, nDevice, PCM_OUT, &cfg);

    if (!pcm_is_ready(p)) {
        printf("Device not ready. Probably due to invalid parameters.");
        pcm_close(p);
        return -1;
    }

    unsigned bufsize = pcm_get_buffer_size(p);
    char *data = new char[bufsize];

    if (!data) {
        printf("Could not allocate %d bytes.\n", bufsize);
        return -1;
    }

    while (read(0, data, bufsize) == bufsize) {
        printf(".");
        if (pcm_write(p, data, bufsize))
            break;
    }

    printf("\b.\nFinished.\n");
    delete [] data;
    pcm_close(p);
    return 0;
}

int main(int argc, char **argv) {
    if (argc >= 2) {
        if (!strcmp(argv[1], "list"))
            return list(argc, argv);
        else if (!strcmp(argv[1], "read"))
            return read(argc, argv);
        else if (!strcmp(argv[1], "read-range"))
            return read_range(argc, argv);
        else if (!strcmp(argv[1], "write"))
            return write(argc, argv);
        else if (!strcmp(argv[1], "write-percentage"))
            return write_percentage(argc, argv);
        else if (!strcmp(argv[1], "play"))
            return play(argc, argv);
    }

    printf("Usage: audiotest <command>\nwhere <command> is one of:\n"
           "list, read, read-range, write, write-percentage, play\n");
    return 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;
}
void play_sample(FILE *file, 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_config config;
    struct pcm *pcm;
    char *buffer;
    int size;
    int num_read;

    memset(&config, 0, sizeof(config));
    config.channels = channels;
    config.rate = rate;
    config.period_size = period_size;
    config.period_count = period_count;
    if (bits == 32)
        config.format = PCM_FORMAT_S32_LE;
    else if (bits == 16)
        config.format = PCM_FORMAT_S16_LE;
    config.start_threshold = 0;
    config.stop_threshold = 0;
    config.silence_threshold = 0;

    if (!sample_is_playable(card, device, channels, rate, bits, period_size, period_count)) {
        return;
    }

    pcm = pcm_open(card, device, PCM_OUT, &config);
    if (!pcm || !pcm_is_ready(pcm)) {
        fprintf(stderr, "Unable to open PCM device %u (%s)\n",
                device, pcm_get_error(pcm));
        return;
    }

    size = pcm_frames_to_bytes(pcm, pcm_get_buffer_size(pcm));
    buffer = malloc(size);
    if (!buffer) {
        fprintf(stderr, "Unable to allocate %d bytes\n", size);
        free(buffer);
        pcm_close(pcm);
        return;
    }

    printf("Playing sample: %u ch, %u hz, %u bit\n", channels, rate, bits);

    /* catch ctrl-c to shutdown cleanly */
    signal(SIGINT, stream_close);

    do {
        num_read = fread(buffer, 1, size, file);
        if (num_read > 0) {
            if (pcm_write(pcm, buffer, num_read)) {
                fprintf(stderr, "Error playing sample\n");
                break;
            }
        }
    } while (!close && num_read > 0);

    free(buffer);
    pcm_close(pcm);
}
bool AudioPlayer::threadLoop()
{
    struct pcm_config config;
    struct pcm *pcm = NULL;
    bool moreChunks = true;
    const struct chunk_fmt* chunkFmt = NULL;
    int bufferSize;
    const uint8_t* wavData;
    size_t wavLength;
    const struct riff_wave_header* wavHeader;

    if (mCurrentFile == NULL) {
        ALOGE("mCurrentFile is NULL");
        return false;
     }

    wavData = (const uint8_t *)mCurrentFile->getDataPtr();
    if (!wavData) {
        ALOGE("Could not access WAV file data");
        goto exit;
    }
    wavLength = mCurrentFile->getDataLength();

    wavHeader = (const struct riff_wave_header *)wavData;
    if (wavLength < sizeof(*wavHeader) || (wavHeader->riff_id != ID_RIFF) ||
        (wavHeader->wave_id != ID_WAVE)) {
        ALOGE("Error: audio file is not a riff/wave file\n");
        goto exit;
    }
    wavData += sizeof(*wavHeader);
    wavLength -= sizeof(*wavHeader);

    do {
        const struct chunk_header* chunkHeader = (const struct chunk_header*)wavData;
        if (wavLength < sizeof(*chunkHeader)) {
            ALOGE("EOF reading chunk headers");
            goto exit;
        }

        wavData += sizeof(*chunkHeader);
        wavLength -=  sizeof(*chunkHeader);

        switch (chunkHeader->id) {
            case ID_FMT:
                chunkFmt = (const struct chunk_fmt *)wavData;
                wavData += chunkHeader->sz;
                wavLength -= chunkHeader->sz;
                break;
            case ID_DATA:
                /* Stop looking for chunks */
                moreChunks = 0;
                break;
            default:
                /* Unknown chunk, skip bytes */
                wavData += chunkHeader->sz;
                wavLength -= chunkHeader->sz;
        }
    } while (moreChunks);

    if (!chunkFmt) {
        ALOGE("format not found in WAV file");
        goto exit;
    }


    memset(&config, 0, sizeof(config));
    config.channels = chunkFmt->num_channels;
    config.rate = chunkFmt->sample_rate;
    config.period_size = mPeriodSize;
    config.period_count = mPeriodCount;
    config.start_threshold = mPeriodSize / 4;
    config.stop_threshold = INT_MAX;
    config.avail_min = config.start_threshold;
    if (chunkFmt->bits_per_sample != 16) {
        ALOGE("only 16 bit WAV files are supported");
        goto exit;
    }
    config.format = PCM_FORMAT_S16_LE;

    pcm = pcm_open(mCard, mDevice, PCM_OUT, &config);
    if (!pcm || !pcm_is_ready(pcm)) {
        ALOGE("Unable to open PCM device (%s)\n", pcm_get_error(pcm));
        goto exit;
    }

    bufferSize = pcm_frames_to_bytes(pcm, pcm_get_buffer_size(pcm));

    while (wavLength > 0) {
        if (exitPending()) goto exit;
        size_t count = bufferSize;
        if (count > wavLength)
            count = wavLength;

        if (pcm_write(pcm, wavData, count)) {
            ALOGE("pcm_write failed (%s)", pcm_get_error(pcm));
            goto exit;
        }
        wavData += count;
        wavLength -= count;
    }

exit:
    if (pcm)
        pcm_close(pcm);
    mCurrentFile->release();
    mCurrentFile = NULL;
    return false;
}