Esempio n. 1
0
static gint
gst_tinyalsa_sink_write (GstAudioSink * asink, gpointer data, guint length)
{
  GstTinyalsaSink *sink = GST_TINYALSA_SINK (asink);
  int ret;

again:
  GST_DEBUG_OBJECT (sink, "Starting write");

  ret = pcm_write (sink->pcm, data, length);
  if (ret == -EPIPE) {
    GST_WARNING_OBJECT (sink, "Got an underrun");

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

    goto again;

  } else if (ret < 0) {
    GST_ERROR_OBJECT (sink, "Could not write data to device: %s",
        pcm_get_error (sink->pcm));
    return -1;
  }

  GST_DEBUG_OBJECT (sink, "Wrote %u bytes", length);

  return length;
}
Esempio n. 2
0
static gboolean
gst_tinyalsa_sink_unprepare (GstAudioSink * asink)
{
  GstTinyalsaSink *sink = GST_TINYALSA_SINK (asink);

  if (pcm_stop (sink->pcm) < 0) {
    GST_ERROR_OBJECT (sink, "Could not stop device: %s",
        pcm_get_error (sink->pcm));
  }

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

  if (pcm_close (sink->pcm)) {
    GST_ERROR_OBJECT (sink, "Could not close device: %s",
        pcm_get_error (sink->pcm));
    return FALSE;
  }

  sink->pcm = NULL;

  gst_caps_replace (&sink->cached_caps, NULL);

  GST_OBJECT_UNLOCK (sink);

  GST_DEBUG_OBJECT (sink, "Device unprepared");

  return TRUE;
}
Esempio n. 3
0
static void
gst_tinyalsa_sink_reset (GstAudioSink * asink)
{
  GstTinyalsaSink *sink = GST_TINYALSA_SINK (asink);

  if (pcm_stop (sink->pcm) < 0) {
    GST_ERROR_OBJECT (sink, "Could not stop device: %s",
        pcm_get_error (sink->pcm));
  }

  if (pcm_prepare (sink->pcm) < 0) {
    GST_ERROR_OBJECT (sink, "Could not prepare device: %s",
        pcm_get_error (sink->pcm));
  }
}
Esempio n. 4
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;
}
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;
}
Esempio n. 6
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;
}
status_t AudioALSACaptureDataProviderBTSCO::GetCaptureTimeStamp(time_info_struct_t *Time_Info, size_t read_size)
{
    ALOGV("%s()", __FUNCTION__);
    ASSERT(mPcm != NULL);

    long ret_ns;
    size_t avail;
    Time_Info->timestamp_get.tv_sec  = 0;
    Time_Info->timestamp_get.tv_nsec = 0;
    Time_Info->frameInfo_get = 0;
    Time_Info->buffer_per_time = 0;
    Time_Info->kernelbuffer_ns = 0;

    //ALOGD("%s(), Going to check pcm_get_htimestamp", __FUNCTION__);
    if (pcm_get_htimestamp(mPcm, &Time_Info->frameInfo_get, &Time_Info->timestamp_get) == 0)
    {
        Time_Info->buffer_per_time = pcm_bytes_to_frames(mPcm, read_size);
        Time_Info->kernelbuffer_ns = 1000000000 / mStreamAttributeSource.sample_rate * (Time_Info->buffer_per_time + Time_Info->frameInfo_get);
        ALOGV("%s pcm_get_htimestamp sec= %ld, nsec=%ld, frameInfo_get = %d, buffer_per_time=%d, ret_ns = %ld\n",
              __FUNCTION__, Time_Info->timestamp_get.tv_sec, Time_Info->timestamp_get.tv_nsec, Time_Info->frameInfo_get,
              Time_Info->buffer_per_time, Time_Info->kernelbuffer_ns);
    }
    else
    {
        ALOGE("%s pcm_get_htimestamp fail %s\n", __FUNCTION__, pcm_get_error(mPcm));
    }
    return NO_ERROR;
}
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;
}
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;
}
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);
}
Esempio n. 12
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;
}
Esempio n. 13
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);
}
Esempio n. 14
0
bool AudioPlaybackLocal::doPlaybackOrRecord(android::sp<Buffer>& buffer)
{
    if (buffer->amountToHandle() < (size_t)mSizes) {
        mSizes = buffer->amountToHandle();
    }
    if (pcm_write(mPcmHandle, buffer->getUnhanledData(), mSizes)) {
        LOGE("AudioPlaybackLocal error %s", pcm_get_error(mPcmHandle));
        return false;
    }
    buffer->increaseHandled(mSizes);
    LOGV("AudioPlaybackLocal::doPlaybackOrRecord %d", buffer->amountHandled());
    return true;
}
Esempio n. 15
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);
}
Esempio n. 16
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;	
   
}
Esempio n. 17
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;
}
bool AudioRecordingLocal::doPlaybackOrRecord(android::sp<Buffer>& buffer)
{
    int toRead = mSizes;
    if (buffer->amountToHandle() < (size_t)mSizes) {
        toRead = buffer->amountToHandle();
    }
    LOGD("recording will read %d", toRead);

    while (toRead > 0) {
        int readSize = (toRead > mBufferSize) ? mBufferSize : toRead;
        if (pcm_read(mPcmHandle, buffer->getUnhanledData(), readSize)) {
            LOGE("AudioRecordingLocal error %s", pcm_get_error(mPcmHandle));
            return false;
        }
        buffer->increaseHandled(readSize);
        toRead -= readSize;
    }
    LOGV("AudioRecordingLocal::doPlaybackOrRecord %d", buffer->amountHandled());
    return true;
}
Esempio n. 19
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;
}
Esempio n. 20
0
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;
    }
}
ssize_t hdmi_out_write(struct audio_stream_out *stream, const void* buffer,
		 size_t bytes)
{
    hdmi_out_t *out = (hdmi_out_t*)stream;
    struct hdmi_device_t *adev = (struct hdmi_device_t *)out->dev;
    ssize_t ret;

    TRACEM("stream=%p buffer=%p bytes=%d", stream, buffer, bytes);

    if (!out->up) {
        if(hdmi_out_open_pcm(out)) {
            ret = -ENOSYS;
	    goto exit;
        }
    }

    if (out->config.channels > 2 && !adev->CEAMap){
        channel_remap(stream, buffer, bytes);
        ret = pcm_write(out->pcm, out->buffcpy, bytes);
    } else {
       ret = pcm_write(out->pcm, buffer, bytes);
    }
exit:
    if (ret != 0) {
        ALOGE("Error writing to HDMI pcm: %s", pcm_get_error(out->pcm));
        hdmi_out_standby((struct audio_stream*)stream);
	unsigned int usecs = bytes * 1000000 /
			audio_stream_frame_size((struct audio_stream*)stream) /
			hdmi_out_get_sample_rate((struct audio_stream*)stream);
	if (usecs >= 1000000L) {
	    usecs = 999999L;
	}
	usleep(usecs);
    }

    return bytes;
}
Esempio n. 22
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;
}
Esempio n. 23
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;
}
Esempio n. 24
0
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;
}
Esempio n. 25
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;
}
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;
}
Esempio n. 27
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;

}
Esempio n. 28
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;
}
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);
}