コード例 #1
0
ファイル: alsa_player.c プロジェクト: 5hanth/dhvani-tts
static void playback_go(int fd, size_t loaded, off64_t count, int rtype, char *name)
{
	int l, r;
	off64_t written = 0;
	off64_t c;

	
	set_params();
	
	while (loaded > chunk_bytes && written < count) {
		if (pcm_write(audiobuf + written, chunk_size) <= 0)
			return;
		written += chunk_bytes;
		loaded -= chunk_bytes;
	}
	if (written > 0 && loaded > 0)
		memmove(audiobuf, audiobuf + written, loaded);

	l = loaded;
	while (written < count) {
		do {
			c = count - written;
			if (c > chunk_bytes)
				c = chunk_bytes;
			c -= l;

			if (c == 0)
				break;
			r = safe_read(fd, audiobuf + l, c);
			if (r < 0) {
				perror(name);
				exit(EXIT_FAILURE);
			}
			fdcount += r;
			if (r == 0)
				break;
			l += r;
		} while ((size_t)l < chunk_bytes);
		l = l * 8 / bits_per_frame;
		r = pcm_write(audiobuf, l);
		if (r != l)
			break;
		r = r * bits_per_frame / 8;
		written += r;
		l = 0;
	}
	snd_pcm_nonblock(handle, 0);
	snd_pcm_drain(handle);
	snd_pcm_nonblock(handle, nonblock);
}
コード例 #2
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;
}
コード例 #3
0
static snd_pcm_sframes_t io_playback_transfer(struct snd_pcm_plugin *plugin,
				    const struct snd_pcm_plugin_channel *src_channels,
				    struct snd_pcm_plugin_channel *dst_channels,
				    snd_pcm_uframes_t frames)
{
	if (snd_BUG_ON(!plugin))
		return -ENXIO;
	if (snd_BUG_ON(!src_channels))
		return -ENXIO;
	if (plugin->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED) {
		return pcm_write(plugin->plug, src_channels->area.addr, frames);
	} else {
		int channel, channels = plugin->dst_format.channels;
		void **bufs = (void**)plugin->extra_data;
		if (snd_BUG_ON(!bufs))
			return -ENXIO;
		for (channel = 0; channel < channels; channel++) {
			if (src_channels[channel].enabled)
				bufs[channel] = src_channels[channel].area.addr;
			else
				bufs[channel] = NULL;
		}
		return pcm_writev(plugin->plug, bufs, frames);
	}
}
コード例 #4
0
ファイル: audio_hw.c プロジェクト: wnpllrzodiac/ffplayer-1
static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
                         size_t bytes)
{
    int ret;
    struct stream_out *out = (struct stream_out *)stream;

    pthread_mutex_lock(&out->dev->lock);
    pthread_mutex_lock(&out->lock);
    if (out->standby) {
        ret = start_output_stream(out);
        if (ret != 0) {
            goto err;
        }
        out->standby = false;
    }

    pcm_write(out->pcm, (void *)buffer, bytes);

    pthread_mutex_unlock(&out->lock);
    pthread_mutex_unlock(&out->dev->lock);

    return bytes;

err:
    pthread_mutex_unlock(&out->lock);

    if (ret != 0) {
        usleep(bytes * 1000000 / audio_stream_frame_size(&stream->common) /
               out_get_sample_rate(&stream->common));
    }

    return bytes;
}
コード例 #5
0
ファイル: file.c プロジェクト: HackLinux/jz4725
/*
 * Play DSP from WAV file:
 */
int PlayDSP(DSPFILE *dfile, WAVFILE *wfile)
{
	UInt32 byte_count = (UInt32) wfile->wavinfo.Samples;
	int bytes;
	int n;
	int byte_modulo;
        int total_bytes;

	//First determine how many bytes are required for each channel's sample:
	switch ( wfile->wavinfo.DataBits ) 
	{
	case 8 :
		byte_count = 1;
		break;
	case 16 :
		byte_count = 2;
		break;
	default :
		printf("Cannot process %u bit samples\n", (unsigned)wfile->wavinfo.DataBits);
		return -1;
	}

	byte_modulo = byte_count;				/* This many bytes per sample */
	byte_count  = wfile->wavinfo.Samples * byte_modulo;	/* Total bytes to process */
        total_bytes = byte_count;

        /* Seek to requested start sample */
        sound_lseek(wfile->fd,wfile->StartSample*byte_modulo,SEEK_CUR);
 
	for (; byte_count > 0 && wfile->wavinfo.DataBytes > 0; byte_count -= (UInt32) n ) 
	{
		bytes = (int) ( byte_count > dfile->dspblksiz ? dfile->dspblksiz : byte_count );
		if ( bytes > wfile->wavinfo.DataBytes )	/* Size bigger than data chunk? */
			bytes = wfile->wavinfo.DataBytes;	/* Data chunk only has this much left */

	//	printf("play databytes:%d bytes:%d n:%d\n",wfile->wavinfo.DataBytes,bytes,n);

		if ( (n = sound_read(wfile->fd,dfile->dspbuf,bytes)) != bytes ) 
		{
			if ( n >= 0 )
				printf("Unexpected EOF reading samples from WAV file\n");
			else	
				printf("Reading samples from WAV file\n");
			goto errxit;
		}
	//	printf("pcm writeing data\n");//treckle
		if (pcm_write(dfile->dspbuf,n) <= 0)
		{
			printf("Writing samples data failed\n");
			goto errxit;
		}
	//	printf("end pcm writeing data\n");//treckle
		wfile->wavinfo.DataBytes -= (UInt32) bytes;	/* We have fewer bytes left to read */
		//printf("dspblksize=%d bytes=%d DataBytes=%d\n", dfile->dspblksiz, bytes, wfile->wavinfo.DataBytes);

        }
	return 0;	/* All samples played successfully */

	errxit:	return -1;	/* Indicate error return */
}
コード例 #6
0
/*
 * I/O
 */
int proxy_write(alsa_device_proxy * proxy, const void *data, unsigned int count)
{
    int ret = pcm_write(proxy->pcm, data, count);
    if (ret == 0) {
        proxy->transferred += count / proxy->frame_size;
    }
    return ret;
}
コード例 #7
0
ssize_t muroard_driver_write(int16_t * data, size_t len, enum muroard_blocking blocking) {
 if ( blocking == MUROARD_BLOCKING_NONE )
  return -1;

 pcm_write(muroard_state_member(driver_vp), data, len);

 return 0;
}
コード例 #8
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);
}
コード例 #9
0
static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
                         size_t bytes)
{
    int ret = 0;
    struct stream_out *out = (struct stream_out *)stream;
    struct audio_device *adev = out ? out->dev : NULL;

    if(adev == NULL) return -ENOSYS;

    ALOGV("%s enter",__func__);

    pthread_mutex_lock(&out->dev->lock);
    pthread_mutex_lock(&out->lock);

    // there is a possibility that the HD interface is open
    // and normal pcm stream is still active. Feed the new
    // interface to normal pcm stream
    if(adev->active_pcm) {
      if(adev->active_pcm != out->pcm)
         out->pcm = adev->active_pcm;
    }

    if ((out->standby) || (!adev->active_pcm)) {
        ret = start_output_stream(out);
        if (ret != 0) {
            goto err;
        }
        out->standby = false;
    }

    if(!out->pcm){
       ALOGD("%s: null handle to write - device already closed",__func__);
       goto err;
    }

    ret = pcm_write(out->pcm, (void *)buffer, bytes);

    ALOGVV("%s: pcm_write returned = %d rate = %d",__func__,ret,out->pcm_config.rate);

err:
    pthread_mutex_unlock(&out->lock);
    pthread_mutex_unlock(&out->dev->lock);


    if (ret != 0) {
        uint64_t duration_ms = ((bytes * 1000)/
                                (audio_stream_frame_size(&stream->common)) /
                                (out_get_sample_rate(&stream->common)));
        ALOGV("%s : silence written", __func__);
        usleep(duration_ms * 1000);
    }

    ALOGV("%s exit",__func__);

    return bytes;
}
コード例 #10
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;
}
コード例 #11
0
ファイル: TinyHardware.cpp プロジェクト: broonie/tinyhardware
ssize_t TinyAudioStreamOut::write(const void* buffer, size_t bytes)
{
    Mutex::Autolock _l(mLock);
    if (!::pcm_is_ready(mPcm)) {
	// This should never happen...
	return BAD_VALUE;
    }

    if (pcm_write(mPcm, buffer, bytes) != 0)
	LOGE("TinyAudioStreamOut::write() failed: %s\n",
	     ::pcm_get_error(mPcm));

    return NO_ERROR;
}
コード例 #12
0
ファイル: adec-wfd-out.cpp プロジェクト: vitmod/libp
EXTERN_TAG int  pcm_output_write(char *buf,unsigned size)
{

	int ret = 0;	
	char *data,  *data_dst;
	char *data_src;	
	char outbuf[8192];
	int total_len,ouput_len;
#ifdef CODE_CALC_VOLUME
	float vol = get_android_stream_volume();
	apply_stream_volume(vol,buf,size);
#endif	
	if(size < 64)
		return 0;	
	if(size > sizeof(outbuf)){
		adec_print("write size tooo big %d \n",size);
	}
	total_len = size + cached_len;

	//adec_print("total_len(%d) =  + cached_len111(%d)", size, cached_len);

	data_src = (char *)cache_buffer_bytes;
	data_dst = (char *)outbuf;



	/*write_back data from cached_buffer*/
	if(cached_len){
		memcpy((void *)data_dst, (void *)data_src, cached_len);
		data_dst += cached_len;
	}
	ouput_len = total_len &(~0x3f);
	data = (char*)buf;

	memcpy((void *)data_dst, (void *)data, ouput_len-cached_len);
	data += (ouput_len-cached_len);
	cached_len = total_len & 0x3f;
	data_src = (char *)cache_buffer_bytes;

	/*save data to cached_buffer*/
	if(cached_len){
		memcpy((void *)data_src, (void *)data, cached_len);
	}	
	ret = pcm_write(wfd_pcm,outbuf,ouput_len);
	if(ret < 0 ){
		adec_print("pcm_output_write failed ? \n");
	}
	//adec_print("write size %d ,ret %d \n",size,ret);
	return ret;
}
コード例 #13
0
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;
}
コード例 #14
0
static int write_tinyalsa(out123_handle *ao, unsigned char *buf, int bytes)
{
	mpg123_tinyalsa_t* ta = (mpg123_tinyalsa_t*)ao->userptr;

	if (ta->pcm)
	{
		if(pcm_write(ta->pcm, buf, bytes))
		{
			if(!AOQUIET)
				error("Error playing sample\n");
			return -1;
		}
	}
	return bytes;
}
コード例 #15
0
ファイル: tone-generator.c プロジェクト: sideb0ard/audio-tool
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;
}
コード例 #16
0
ssize_t AudioALSAPlaybackHandlerBTSCO::write(const void *buffer, size_t bytes)
{
    ALOGV("%s(), buffer = %p, bytes = %d", __FUNCTION__, buffer, bytes);

    if (mPcm == NULL)
    {
        ALOGE("%s(), mPcm == NULL, return", __FUNCTION__);
        return bytes;
    }

    // const -> to non const
    void *pBuffer = const_cast<void *>(buffer);
    ASSERT(pBuffer != NULL);


    // SRC
    void *pBufferAfterBliSrc = NULL;
    uint32_t bytesAfterBliSrc = 0;
    doBliSrc(pBuffer, bytes, &pBufferAfterBliSrc, &bytesAfterBliSrc);


    // bit conversion
    void *pBufferAfterBitConvertion = NULL;
    uint32_t bytesAfterBitConvertion = 0;
    doBitConversion(pBufferAfterBliSrc, bytesAfterBliSrc, &pBufferAfterBitConvertion, &bytesAfterBitConvertion);


    // write data to pcm driver
    WritePcmDumpData(pBufferAfterBitConvertion, bytesAfterBitConvertion);
    int retval = pcm_write(mPcm, pBufferAfterBitConvertion, bytesAfterBitConvertion);


    if (retval != 0)
    {
        ALOGE("%s(), pcm_write() error, retval = %d", __FUNCTION__, retval);
    }

    return bytes;
}
ssize_t AudioStreamOutALSA::write(const void *buffer, size_t bytes)
{
    int period_size;
    char *use_case;

    ALOGV("write:: buffer %p, bytes %d", buffer, bytes);

    snd_pcm_sframes_t n = 0;
    size_t            sent = 0;
    status_t          err;

    int write_pending = bytes;

    if((strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) &&
       (strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
        mParent->mLock.lock();
        /* PCM handle might be closed and reopened immediately to flush
         * the buffers, recheck and break if PCM handle is valid */
        if (mHandle->handle == NULL && mHandle->rxHandle == NULL) {
            ALOGV("mDevices =0x%x", mDevices);
            if(mParent->isExtOutDevice(mDevices)) {
                ALOGV("StreamOut write - mRouteAudioToExtOut = %d ", mParent->mRouteAudioToExtOut);
                mParent->mRouteAudioToExtOut = true;
                if(mParent->mExtOutStream == NULL) {
                    mParent->switchExtOut(mDevices);
                }
            }
            ALOGV("write: mHandle->useCase: %s", mHandle->useCase);
            snd_use_case_get(mHandle->ucMgr, "_verb", (const char **)&use_case);
            if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
                if(!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP)) {
                    strlcpy(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL,
                            sizeof(SND_USE_CASE_VERB_IP_VOICECALL));
                } else if(!strcmp(mHandle->useCase,SND_USE_CASE_MOD_PLAY_MUSIC2)) {
                    strlcpy(mHandle->useCase, SND_USE_CASE_VERB_HIFI2,
                            sizeof(SND_USE_CASE_MOD_PLAY_MUSIC2));
                } else if (!strcmp(mHandle->useCase,SND_USE_CASE_MOD_PLAY_MUSIC)) {
                    strlcpy(mHandle->useCase, SND_USE_CASE_VERB_HIFI,
                            sizeof(SND_USE_CASE_MOD_PLAY_MUSIC));
                } else if(!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC)) {
                    strlcpy(mHandle->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC,
                            sizeof(SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC));
                }
            } else {
                if(!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) {
                    strlcpy(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP,
                            sizeof(SND_USE_CASE_MOD_PLAY_VOIP));
                } else if(!strcmp(mHandle->useCase,SND_USE_CASE_VERB_HIFI2)) {
                    strlcpy(mHandle->useCase, SND_USE_CASE_MOD_PLAY_MUSIC2,
                            sizeof(SND_USE_CASE_MOD_PLAY_MUSIC2));
                } else if (!strcmp(mHandle->useCase,SND_USE_CASE_VERB_HIFI)) {
                    strlcpy(mHandle->useCase, SND_USE_CASE_MOD_PLAY_MUSIC,
                            sizeof(SND_USE_CASE_MOD_PLAY_MUSIC));
                } else if(!strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC)) {
                    strlcpy(mHandle->useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC,
                            sizeof(SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC));
                }
            }
            free(use_case);
            if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) ||
               (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
#ifdef QCOM_USBAUDIO_ENABLED
                if((mDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
                      (mDevices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)||
                      (mDevices & AudioSystem::DEVICE_OUT_PROXY)) {
                    mHandle->module->route(mHandle, mDevices , mParent->mode());
                }else
#endif
                {
                  mHandle->module->route(mHandle, mDevices , AUDIO_MODE_IN_COMMUNICATION);
                }
#ifdef QCOM_USBAUDIO_ENABLED
            } else if((mDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
                      (mDevices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)||
                      (mDevices & AudioSystem::DEVICE_OUT_PROXY)) {
                mHandle->module->route(mHandle, mDevices , mParent->mode());
#endif
            } else {
                  mHandle->module->route(mHandle, mDevices , mParent->mode());
            }
            if (!strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI) ||
                !strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI2) ||
                !strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC) ||
                !strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) {
                snd_use_case_set(mHandle->ucMgr, "_verb", mHandle->useCase);
            } else {
                snd_use_case_set(mHandle->ucMgr, "_enamod", mHandle->useCase);
            }
            if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) ||
              (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
                 err = mHandle->module->startVoipCall(mHandle);
            }
            else
                 mHandle->module->open(mHandle);
            if(mHandle->handle == NULL) {
                ALOGE("write:: device open failed");
                mParent->mLock.unlock();
                return bytes;
            }
#ifdef QCOM_USBAUDIO_ENABLED
            if((mDevices == AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET)||
                   (mDevices == AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)){
                if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) ||
                   (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
                    ALOGV("Setting VOIPCALL bit here, musbPlaybackState %d", mParent->musbPlaybackState);
                    mParent->musbPlaybackState |= USBPLAYBACKBIT_VOIPCALL;
                } else {
                    mParent->startUsbPlaybackIfNotStarted();
                    ALOGV("enabling music, musbPlaybackState: %d ", mParent->musbPlaybackState);
                    mParent->musbPlaybackState |= USBPLAYBACKBIT_MUSIC;
                }
            }
#endif
        }
        if (mParent->mRouteAudioToExtOut) {
            mUseCase = mParent->useCaseStringToEnum(mHandle->useCase);
            if (! (mParent->getExtOutActiveUseCases_l() & mUseCase )){
                ALOGD("startPlaybackOnExtOut_l from write :: useCase = %s", mHandle->useCase);
                status_t err = NO_ERROR;
                err = mParent->startPlaybackOnExtOut_l(mUseCase);
                if(err) {
                    ALOGE("startPlaybackOnExtOut_l from write return err = %d", err);
                    mParent->mLock.unlock();
                    return err;
                }
            }
        }
        mParent->mLock.unlock();
    }

#ifdef QCOM_USBAUDIO_ENABLED
    if(((mDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET) ||
        (mDevices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)) &&
        (!mParent->musbPlaybackState)) {
        mParent->mLock.lock();
        mParent->startUsbPlaybackIfNotStarted();
        ALOGV("Starting playback on USB");
        if(!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL) ||
           !strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP)) {
            ALOGV("Setting VOIPCALL bit here, musbPlaybackState %d", mParent->musbPlaybackState);
            mParent->musbPlaybackState |= USBPLAYBACKBIT_VOIPCALL;
        }else{
            ALOGV("enabling music, musbPlaybackState: %d ", mParent->musbPlaybackState);
            mParent->musbPlaybackState |= USBPLAYBACKBIT_MUSIC;
        }
        mParent->mLock.unlock();
    }
#endif

    period_size = mHandle->periodSize;
    do {
        if (write_pending < period_size) {
            write_pending = period_size;
        }
        if((mParent->mVoipStreamCount) && (mHandle->rxHandle != 0)) {
            n = pcm_write(mHandle->rxHandle,
                     (char *)buffer + sent,
                      period_size);
        } else if (mHandle->handle != 0){
            n = pcm_write(mHandle->handle,
                     (char *)buffer + sent,
                      period_size);
        }
        if (n < 0) {
            mParent->mLock.lock();
            if (mHandle->handle != NULL) {
                ALOGE("pcm_write returned error %d, trying to recover\n", n);
                pcm_close(mHandle->handle);
                mHandle->handle = NULL;
                if((!strncmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL, strlen(SND_USE_CASE_VERB_IP_VOICECALL))) ||
                  (!strncmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP, strlen(SND_USE_CASE_MOD_PLAY_VOIP)))) {
                     pcm_close(mHandle->rxHandle);
                     mHandle->rxHandle = NULL;
                     mHandle->module->startVoipCall(mHandle);
                }
                else
                {
                    if (mParent->mALSADevice->mADSPState == ADSP_UP_AFTER_SSR) {
                        ALOGD("SSR Case: Call device switch to apply AMIX controls.");
                        mHandle->module->route(mHandle, mDevices , mParent->mode());
                        // In-case of multiple streams only one stream will be resumed
                        // after resetting mADSPState to ADSP_UP with output device routed
                        mParent->mALSADevice->mADSPState = ADSP_UP;

                        if(mParent->isExtOutDevice(mDevices)) {
                           ALOGV("StreamOut write - mRouteAudioToExtOut = %d ", mParent->mRouteAudioToExtOut);
                           mParent->mRouteAudioToExtOut = true;
                        }
                    }
                    mHandle->module->open(mHandle);
                }
                if(mHandle->handle == NULL) {
                   ALOGE("write:: device re-open failed");
                   mParent->mLock.unlock();
                   return bytes;
                }
            }
            mParent->mLock.unlock();
            continue;
        }
        else {
            mFrameCount += n;
            sent += static_cast<ssize_t>((period_size));
            write_pending -= period_size;
        }

    } while ((mHandle->handle||(mHandle->rxHandle && mParent->mVoipStreamCount)) && sent < bytes);

    return sent;
}
コード例 #18
0
ssize_t AudioALSAPlaybackHandlerNormal::write(const void *buffer, size_t bytes)
{
    ALOGV("%s(), buffer = %p, bytes = %d", __FUNCTION__, buffer, bytes);

    if (mPcm == NULL)
    {
        ALOGE("%s(), mPcm == NULL, return", __FUNCTION__);
        return bytes;
    }

    // const -> to non const
    void *pBuffer = const_cast<void *>(buffer);
    ASSERT(pBuffer != NULL);

#ifdef DEBUG_LATENCY
    clock_gettime(CLOCK_REALTIME, &mNewtime);
    latencyTime[0] = calc_time_diff(mNewtime, mOldtime);
    mOldtime = mNewtime;
#endif

    // stereo to mono for speaker
    if (mStreamAttributeSource->audio_format == AUDIO_FORMAT_PCM_16_BIT) // AudioMixer will perform stereo to mono when 32-bit
    {
        doStereoToMonoConversionIfNeed(pBuffer, bytes);
    }


    // post processing (can handle both Q1P16 and Q1P31 by audio_format_t)
    void *pBufferAfterPostProcessing = NULL;
    uint32_t bytesAfterPostProcessing = 0;
    doPostProcessing(pBuffer, bytes, &pBufferAfterPostProcessing, &bytesAfterPostProcessing);


    // SRC
    void *pBufferAfterBliSrc = NULL;
    uint32_t bytesAfterBliSrc = 0;
    doBliSrc(pBufferAfterPostProcessing, bytesAfterPostProcessing, &pBufferAfterBliSrc, &bytesAfterBliSrc);


    // bit conversion
    void *pBufferAfterBitConvertion = NULL;
    uint32_t bytesAfterBitConvertion = 0;
    doBitConversion(pBufferAfterBliSrc, bytesAfterBliSrc, &pBufferAfterBitConvertion, &bytesAfterBitConvertion);

    // data pending
    void *pBufferAfterPending = NULL;
    uint32_t bytesAfterpending = 0;
    dodataPending(pBufferAfterBitConvertion, bytesAfterBitConvertion, &pBufferAfterPending, &bytesAfterpending);

    // pcm dump
    WritePcmDumpData(pBufferAfterPending, bytesAfterpending);

#ifdef DEBUG_LATENCY
    clock_gettime(CLOCK_REALTIME, &mNewtime);
    latencyTime[1] = calc_time_diff(mNewtime, mOldtime);
    mOldtime = mNewtime;
#endif


    // write data to pcm driver
    int retval = pcm_write(mPcm, pBufferAfterPending, bytesAfterpending);

#ifdef DEBUG_LATENCY
    clock_gettime(CLOCK_REALTIME, &mNewtime);
    latencyTime[2] = calc_time_diff(mNewtime, mOldtime);
    mOldtime = mNewtime;
#endif

#if 1 // TODO(Harvey, Wendy), temporary disable Voice Unlock until 24bit ready
    //============Voice UI&Unlock REFERECE=============
    AudioVUnlockDL *VUnlockhdl = AudioVUnlockDL::getInstance();
    if (VUnlockhdl != NULL)
    {
        // get remain time
        //VUnlockhdl->SetDownlinkStartTime(ret_ms);
        VUnlockhdl->GetFirstDLTime();

        //VUnlockhdl->SetInputStandBy(false);
        if (mStreamAttributeSource->output_devices & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
            mStreamAttributeSource->output_devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE)
        {
            memset((void *)pBufferAfterBitConvertion, 0, bytesAfterBitConvertion);
        }
        VUnlockhdl->WriteStreamOutToRing(pBufferAfterBitConvertion, bytesAfterBitConvertion);
    }
    //===========================================
#endif


    if (retval != 0)
    {
        ALOGE("%s(), pcm_write() error, retval = %d", __FUNCTION__, retval);
    }

#ifdef DEBUG_LATENCY
    ALOGD("AudioALSAPlaybackHandlerNormal::write (-) latency_in_us,%1.6lf,%1.6lf,%1.6lf", latencyTime[0], latencyTime[1], latencyTime[2]);
#endif

    return bytes;
}
コード例 #19
0
ファイル: aoutput.cpp プロジェクト: FredSanders/emacs.d
int
playTTS (int count)
{
  pcm_write (waveBuffer, count);
  return 0;
}
コード例 #20
0
static int stream_transfer(struct stream_transfer *stream_transfer)
{

	struct dev_stream *stream_sender;
	struct dev_stream *stream_receiver;
	int size_transfer = 0;
	int ret   =0;
	int exit_flag   =0;
	int i   =0;
	short* Srcptr;
	short* Drcptr;

	stream_sender = stream_transfer->stream_sender;
	stream_receiver = stream_transfer->stream_receiver;
	size_transfer = stream_sender->buf_size;


#ifdef  START_ZERO_BUFFER
	/* 消除开头杂音 */
	memset(stream_sender->buf, 0, stream_sender->buf_size);
	pcm_write(stream_receiver->dev, stream_sender->buf, stream_sender->buf_size);
#endif

	while( 1 ){
		if ( (!stream_transfer->voice_thread_run_flag) || (exit_flag == 1)){
			break;	
		}

		ret = pcm_read(stream_sender->dev, stream_sender->buf, size_transfer);
		if (ret != 0) {
			exit_flag = 1;
			ALOGE("err: read codec err:%s, ret=%d", strerror(errno), ret);
			break;
		}

		if ( (!stream_transfer->voice_thread_run_flag) || (exit_flag == 1)){
			break;	
		}

		ret = pcm_write(stream_receiver->dev, stream_sender->buf, size_transfer);
		if (ret != 0) {
			exit_flag = 1;
			ALOGE("err: write pcm err:%s, ret=%d", strerror(errno), ret);
		}

		if ( (!stream_transfer->voice_thread_run_flag) || (exit_flag == 1)){
			break;	
		}

		if (stream_transfer->record_flag == 1){
			//是上行,还是下行.
			if (stream_transfer->voice_direction == UPSTREAM){
				Srcptr = (short*)(stream_sender->buf);
				Drcptr = (short*)(record_data.record_buf + (record_data.lenwriteup%record_data.record_lenth));
				if(record_data.lenwriteup >= record_data.lenwritedown)
				{
					memcpy(Drcptr,Srcptr,size_transfer);
				}
				else
				{
					int i;
					for(i=0;i<size_transfer/2;i++,Drcptr++)
					{
						*Drcptr = (*Drcptr + *Srcptr++)/2;
					}
					record_data.lenwrite += size_transfer;
//				        sem_post(&sem_record);
				}
				record_data.lenwriteup += size_transfer;
				//ALOGD("stream is upload");
			} else {
				Srcptr = (short*)(stream_sender->buf);
				Drcptr = (short*)(record_data.record_buf + (record_data.lenwritedown%record_data.record_lenth));
				if(record_data.lenwritedown >= record_data.lenwriteup)
				{
					memcpy(Drcptr,Srcptr,size_transfer);
				}
				else
				{

					for(i=0;i<size_transfer/2;i++,Drcptr++)
					{
						*Drcptr = ((int)*Drcptr + (int)(*Srcptr++))/2;
					}
					record_data.lenwrite += size_transfer;
//				        sem_post(&sem_record);
				}
				record_data.lenwritedown += size_transfer;
				//ALOGD("stream is download");
			}	
		        sem_post(&sem_record);
		}

		//ALOGD("pcm running ... , type=%d ",stream_sender->type);
		if ( (!stream_transfer->voice_thread_run_flag) || (exit_flag == 1)){
			break;	
		}
	}
	return 0;
}
コード例 #21
0
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);
}
コード例 #22
0
int play_file(unsigned rate, unsigned channels, int fd, unsigned count,
              unsigned flags, const char *device)
{
    struct pcm *pcm;
    struct mixer *mixer;
    struct pcm_ctl *ctl = NULL;
    unsigned bufsize;
    char *data;
    long avail;
    long frames;
    int nfds = 1;
    struct snd_xferi x;
    unsigned offset = 0;
    int err;
    static int start = 0;
    struct pollfd pfd[1];

    flags |= PCM_OUT;

    if (channels == 1)
        flags |= PCM_MONO;
    else
        flags |= PCM_STEREO;

    if (debug)
        flags |= DEBUG_ON;
    else
        flags |= DEBUG_OFF;

    pcm = pcm_open(flags, device);
    if (pcm < 0)
        return pcm;

    if (!pcm_ready(pcm)) {
        pcm_close(pcm);
        return -EBADFD;
    }
    pcm->channels = channels;
    pcm->rate = rate;
    pcm->flags = flags;
    if (set_params(pcm)) {
        fprintf(stderr, "Aplay:params setting failed\n");
        pcm_close(pcm);
        return -errno;
    }

    if (!pcm_flag) {
       if (pcm_prepare(pcm)) {
          fprintf(stderr, "Aplay:Failed in pcm_prepare\n");
          pcm_close(pcm);
          return -errno;
       }
        while(1);
    }

    if (flags & PCM_MMAP) {
        if (mmap_buffer(pcm)) {
             fprintf(stderr, "Aplay:params setting failed\n");
             pcm_close(pcm);
             return -errno;
        }
       if (pcm_prepare(pcm)) {
          fprintf(stderr, "Aplay:Failed in pcm_prepare\n");
          pcm_close(pcm);
          return -errno;
       }
        bufsize = pcm->period_size;
        if (debug)
          fprintf(stderr, "Aplay:bufsize = %d\n", bufsize);
        data = calloc(1, bufsize);
        if (!data) {
           fprintf(stderr, "Aplay:could not allocate %d bytes\n", count);
           pcm_close(pcm);
           return -ENOMEM;
        }

        pfd[0].fd = pcm->fd;
        pfd[0].events = POLLOUT;
        while (read(fd, data, bufsize) == bufsize) {
            x.buf = data;
            x.frames = (pcm->flags & PCM_MONO) ? (bufsize / 2) : (bufsize / 4);
            frames = x.frames;

            for (;;) {
                if (!pcm->running) {
                    if (pcm_prepare(pcm))
                        return --errno;
                    pcm->running = 1;
                    start = 0;
                }
                pcm->sync_ptr->flags = SNDRV_PCM_SYNC_PTR_APPL | SNDRV_PCM_SYNC_PTR_AVAIL_MIN;//SNDRV_PCM_SYNC_PTR_HWSYNC;
                err = sync_ptr(pcm);
                if (err == EPIPE) {
                     fprintf(stderr, "Aplay:Failed in sync_ptr \n");
                     /* we failed to make our window -- try to restart */
                     pcm->underruns++;
                     pcm->running = 0;
                     continue;
                }
                avail = pcm_avail(pcm);
                if (debug)
                    fprintf(stderr, "Aplay:avail 1 = %d frames = %d\n",avail, frames);
                if (avail < 0)
                    return avail;
                if (avail < pcm->sw_p->avail_min) {
                    poll(pfd, nfds, TIMEOUT_INFINITE);
                    continue;
                }
                if (x.frames > avail)
                    frames = avail;
                if (debug) {
                    fprintf(stderr, "Aplay:avail = %d frames = %d\n",avail, frames);
                    fprintf(stderr, "Aplay:sync_ptr->s.status.hw_ptr %ld  pcm->buffer_size %d  sync_ptr->c.control.appl_ptr %ld\n",
                            pcm->sync_ptr->s.status.hw_ptr,
                            pcm->buffer_size,
                            pcm->sync_ptr->c.control.appl_ptr);
                }
                err = mmap_transfer(pcm, data , offset, frames);
                if (err == EPIPE) {
                    fprintf(stderr, "Aplay:Failed in mmap_transfer \n");
                    /* we failed to make our window -- try to restart */
                    pcm->underruns++;
                    pcm->running = 0;
                    continue;
                }
                x.frames -= frames;
                pcm->sync_ptr->c.control.appl_ptr += frames;
                pcm->sync_ptr->flags = 0;

                err = sync_ptr(pcm);
                if (err == EPIPE) {
                    fprintf(stderr, "Aplay:Failed in sync_ptr 2 \n");
                    /* we failed to make our window -- try to restart */
                    pcm->underruns++;
                    pcm->running = 0;
                    continue;
                }
                if (debug) {
                    fprintf(stderr, "Aplay:sync_ptr 2 \n");
                    fprintf(stderr, "Aplay:sync_ptr->s.status.hw_ptr %ld  pcm->buffer_size %d  sync_ptr->c.control.appl_ptr %ld\n",
                            pcm->sync_ptr->s.status.hw_ptr,
                            pcm->buffer_size,
                            pcm->sync_ptr->c.control.appl_ptr);
                }
                if (pcm->sync_ptr->c.control.appl_ptr >= pcm->sw_p->start_threshold) {
                    if(start)
                        goto xyz;
                    if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_START)) {
                        err = -errno;
                        if (errno == EPIPE) {
                            fprintf(stderr, "Aplay:Failed in SNDRV_PCM_IOCTL_START\n");
                            /* we failed to make our window -- try to restart */
                            pcm->underruns++;
                            pcm->running = 0;
                            continue;
                        } else {
                            fprintf(stderr, "Aplay:Error no %d \n", errno);
                            return -errno;
                        }
                    } else
                        start = 1;
                }
xyz:
                offset += frames;
                break;
            }
        }
    } else {
       if (pcm_prepare(pcm)) {
          fprintf(stderr, "Aplay:Failed in pcm_prepare\n");
          pcm_close(pcm);
          return -errno;
       }
        bufsize = pcm->period_size;
        if (debug)
          fprintf(stderr, "Aplay:bufsize = %d\n", bufsize);
        data = calloc(1, bufsize);
        if (!data) {
            fprintf(stderr, "Aplay:could not allocate %d bytes\n", count);
            pcm_close(pcm);
            return -ENOMEM;
        }

        while (read(fd, data, bufsize) == bufsize) {
            if (pcm_write(pcm, data, bufsize)){
                fprintf(stderr, "Aplay: pcm_write failed\n");
                break;
            }
        }
    }
    fprintf(stderr, "Aplay: Done playing\n");
    free(data);
    pcm_close(pcm);
    return 0;
}
コード例 #23
0
ssize_t AudioALSAPlaybackHandlerSphDL::write(const void *buffer, size_t bytes)
{
    ALOGV("%s(), buffer = %p, bytes = %d", __FUNCTION__, buffer, bytes);

    if (mPcm == NULL)
    {
        ALOGE("%s(), mPcm == NULL, return", __FUNCTION__);
        return bytes;
    }

    // const -> to non const
    void *pBuffer = const_cast<void *>(buffer);
    ASSERT(pBuffer != NULL);

#ifdef DEBUG_LATENCY
    clock_gettime(CLOCK_REALTIME, &mNewtime);
    latencyTime[0] = calc_time_diff(mNewtime, mOldtime);
    mOldtime = mNewtime;
#endif

    // stereo to mono for speaker
    if (mStreamAttributeSource->audio_format == AUDIO_FORMAT_PCM_16_BIT) // AudioMixer will perform stereo to mono when 32-bit
    {
        doStereoToMonoConversionIfNeed(pBuffer, bytes);
    }


    // post processing (can handle both Q1P16 and Q1P31 by audio_format_t)
    void *pBufferAfterPostProcessing = NULL;
    uint32_t bytesAfterPostProcessing = 0;
    doPostProcessing(pBuffer, bytes, &pBufferAfterPostProcessing, &bytesAfterPostProcessing);


    // SRC
    void *pBufferAfterBliSrc = NULL;
    uint32_t bytesAfterBliSrc = 0;
    doBliSrc(pBufferAfterPostProcessing, bytesAfterPostProcessing, &pBufferAfterBliSrc, &bytesAfterBliSrc);


    // bit conversion
    void *pBufferAfterBitConvertion = NULL;
    uint32_t bytesAfterBitConvertion = 0;
    doBitConversion(pBufferAfterBliSrc, bytesAfterBliSrc, &pBufferAfterBitConvertion, &bytesAfterBitConvertion);


    // pcm dump
    WritePcmDumpData(pBufferAfterBitConvertion, bytesAfterBitConvertion);

#ifdef DEBUG_LATENCY
    clock_gettime(CLOCK_REALTIME, &mNewtime);
    latencyTime[1] = calc_time_diff(mNewtime, mOldtime);
    mOldtime = mNewtime;
#endif

    // write data to pcm driver
    int retval = pcm_write(mPcm, pBufferAfterBitConvertion, bytesAfterBitConvertion);

#ifdef DEBUG_LATENCY
    clock_gettime(CLOCK_REALTIME, &mNewtime);
    latencyTime[2] = calc_time_diff(mNewtime, mOldtime);
    mOldtime = mNewtime;
#endif

    if (retval != 0)
    {
        ALOGE("%s(), pcm_write() error, retval = %d", __FUNCTION__, retval);
    }

#ifdef DEBUG_LATENCY
    ALOGD("AudioALSAPlaybackHandlerSphDL::write (-) latency_in_us,%1.6lf,%1.6lf,%1.6lf", latencyTime[0], latencyTime[1], latencyTime[2]);
#endif

    return bytes;
}
コード例 #24
0
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;
}
コード例 #25
0
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;
}
コード例 #26
0
/*
 * I/O
 */
int proxy_write(const alsa_device_proxy * proxy, const void *data, unsigned int count)
{
    return pcm_write(proxy->pcm, data, count);
}
コード例 #27
0
ファイル: audio.c プロジェクト: crpalmer/pi_lib
bool
audio_play_buffer(audio_t *c, const unsigned char *buffer, size_t size)
{
    return pcm_write(c->pcm, buffer, size) == 0;
}
コード例 #28
0
static int stream_transfer(struct stream_transfer *stream_transfer)
{

	struct dev_stream *stream_sender;
	struct dev_stream *stream_receiver;
	short* Srcptr;
	short* Drcptr;
	int size_transfer = 0;
	int ret   =0;
	int exit_flag   =0;
    	int i=0;

	stream_sender = stream_transfer->stream_sender;
	stream_receiver = stream_transfer->stream_receiver;
	size_transfer = stream_sender->buf_size;


#ifdef  START_ZERO_BUFFER
	/* 消除开头杂音 */
	memset(stream_sender->buf, 0, stream_sender->buf_size);
	pcm_write(stream_receiver->dev, stream_sender->buf, stream_sender->buf_size);
#endif


	ret =pcm_wait(stream_sender->dev, 0);
	ret =pcm_wait(stream_receiver->dev, 0);

	pcm_stop(stream_receiver->dev);
	pcm_start(stream_receiver->dev);


	/* 消除开头pa音 */
	memset(stream_sender->buf, 0, stream_sender->buf_size);
	pcm_write(stream_receiver->dev, stream_sender->buf, stream_sender->buf_size);


	while( 1 ){

		if ( (!stream_transfer->voice_thread_run_flag)){
			break;	
		}
#if 0
		if (SNDRV_PCM_STATE_XRUN == get_pcm_state(stream_sender->dev) ){
			//ALOGD("read  SNDRV_PCM_STATE_XRUN ");
			if(ioctl(stream_sender->dev->fd, SNDRV_PCM_IOCTL_PREPARE)){
                		ALOGE("in read, fail to prepare SNDRV_PCM_STATE_XRUN ");
			}
			//usleep(3 * 1000);
			ret =pcm_wait(stream_sender->dev, 0);
			//ALOGD("pcm_read, pcm_wait ret=%d", ret);

			//ALOGD("read after prepare state:%d ",get_pcm_state(stream_sender->dev));
		}
#endif
		ret = pcm_read(stream_sender->dev, stream_sender->buf, size_transfer);
		if (ret != 0) {
			//exit_flag = 1;
			ALOGE("err: read codec err:%s, ret=%d", strerror(errno), ret);
			//break;
		}



		if ( (!stream_transfer->voice_thread_run_flag)){
			break;	
		}
#if 0
		if (SNDRV_PCM_STATE_XRUN == get_pcm_state(stream_receiver->dev) ){
			//ALOGD("write  SNDRV_PCM_STATE_XRUN ");
			pcm_stop(stream_receiver->dev);
			usleep(3 * 1000);
			//ALOGD("write after stop state:%d ",get_pcm_state(stream_receiver->dev));
			pcm_start(stream_receiver->dev);


			ret =pcm_wait(stream_receiver->dev, 0);
			//ALOGD("pcm_write, pcm_wait ret=%d", ret);

			//usleep(3 * 1000);
			//ALOGD("write after prepare state:%d ",get_pcm_state(stream_receiver->dev));
		}
#endif
		ret = pcm_write(stream_receiver->dev, stream_sender->buf, size_transfer);
		if (ret != 0) {
			//exit_flag = 1;
			ALOGE("err: write pcm err:%s, ret=%d", strerror(errno), ret);
		}

		if ( (!stream_transfer->voice_thread_run_flag)){
			break;	
		}



		if (stream_transfer->record_flag == 1){
			//是上行,还是下行.
			if (stream_transfer->voice_direction == UPSTREAM){
				Srcptr = (short*)(stream_sender->buf);
				Drcptr = (short*)(record_data.record_buf + (record_data.lenwriteup%record_data.record_lenth));
				if(record_data.lenwriteup >= record_data.lenwritedown)
				{
					memcpy(Drcptr,Srcptr,size_transfer);
				}
				else
				{
					int i;
					for(i=0;i<size_transfer/2;i++,Drcptr++)
					{
						*Drcptr = (*Drcptr + *Srcptr++)/2;
					}
					record_data.lenwrite += size_transfer;

				}
				record_data.lenwriteup += size_transfer;
				//ALOGD("stream is upload");
			} else {
				Srcptr = (short*)(stream_sender->buf);
				Drcptr = (short*)(record_data.record_buf + (record_data.lenwritedown%record_data.record_lenth));
				if(record_data.lenwritedown >= record_data.lenwriteup)
				{
					memcpy(Drcptr,Srcptr,size_transfer);
				}
				else
				{

					for(i=0;i<size_transfer/2;i++,Drcptr++)
					{
						*Drcptr = ((int)*Drcptr + (int)(*Srcptr++))/2;
					}
					record_data.lenwrite += size_transfer;
				}
				record_data.lenwritedown += size_transfer;
			}	
			sem_post(&g_sem_record);
		}

		if ( (!stream_transfer->voice_thread_run_flag)){
			break;	
		}
	}

	return 0;
}
コード例 #29
0
static int play_file(unsigned rate, unsigned channels, int fd,
              unsigned flags, const char *device, unsigned data_sz)
{
    struct pcm *pcm;
    struct mixer *mixer;
    struct pcm_ctl *ctl = NULL;
    unsigned bufsize;
    char *data;
    long avail;
    long frames;
    int nfds = 1;
    struct snd_xferi x;
    unsigned offset = 0;
    int err;
    static int start = 0;
    struct pollfd pfd[1];
    int remainingData = 0;

    flags |= PCM_OUT;

    if (channels == 1)
        flags |= PCM_MONO;
    else if (channels == 6)
	flags |= PCM_5POINT1;
    else
        flags |= PCM_STEREO;

    if (debug)
        flags |= DEBUG_ON;
    else
        flags |= DEBUG_OFF;

    pcm = pcm_open(flags, device);
    if (pcm < 0)
        return pcm;

    if (!pcm_ready(pcm)) {
        pcm_close(pcm);
        return -EBADFD;
    }

#ifdef QCOM_COMPRESSED_AUDIO_ENABLED
    if (compressed) {
       struct snd_compr_caps compr_cap;
       struct snd_compr_params compr_params;
       if (ioctl(pcm->fd, SNDRV_COMPRESS_GET_CAPS, &compr_cap)) {
          fprintf(stderr, "Aplay: SNDRV_COMPRESS_GET_CAPS, failed Error no %d \n", errno);
          pcm_close(pcm);
          return -errno;
       }
       if (!period)
           period = compr_cap.min_fragment_size;
           switch (get_compressed_format(compr_codec)) {
           case FORMAT_MP3:
               compr_params.codec.id = compr_cap.codecs[FORMAT_MP3];
               break;
           case FORMAT_AC3_PASS_THROUGH:
               compr_params.codec.id = compr_cap.codecs[FORMAT_AC3_PASS_THROUGH];
               printf("codec -d = %x\n", compr_params.codec.id);
               break;
           default:
               break;
           }
       if (ioctl(pcm->fd, SNDRV_COMPRESS_SET_PARAMS, &compr_params)) {
          fprintf(stderr, "Aplay: SNDRV_COMPRESS_SET_PARAMS,failed Error no %d \n", errno);
          pcm_close(pcm);
          return -errno;
       }
    }
#endif
    pcm->channels = channels;
    pcm->rate = rate;
    pcm->flags = flags;
    pcm->format = format;
    if (set_params(pcm)) {
        fprintf(stderr, "Aplay:params setting failed\n");
        pcm_close(pcm);
        return -errno;
    }

    if (!pcm_flag) {
       if (pcm_prepare(pcm)) {
          fprintf(stderr, "Aplay:Failed in pcm_prepare\n");
          pcm_close(pcm);
          return -errno;
       }
       if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_START)) {
          fprintf(stderr, "Aplay: Hostless IOCTL_START Error no %d \n", errno);
          pcm_close(pcm);
          return -errno;
       }
        while(1);
    }

    remainingData = data_sz;

    if (flags & PCM_MMAP) {
        u_int8_t *dst_addr = NULL;
        struct snd_pcm_sync_ptr *sync_ptr1 = pcm->sync_ptr;
        if (mmap_buffer(pcm)) {
             fprintf(stderr, "Aplay:params setting failed\n");
             pcm_close(pcm);
             return -errno;
        }
        if (pcm_prepare(pcm)) {
          fprintf(stderr, "Aplay:Failed in pcm_prepare\n");
          pcm_close(pcm);
          return -errno;
        }

        bufsize = pcm->period_size;
        if (debug)
          fprintf(stderr, "Aplay:bufsize = %d\n", bufsize);

        pfd[0].fd = pcm->timer_fd;
        pfd[0].events = POLLIN;

        frames = (pcm->flags & PCM_MONO) ? (bufsize / 2) : (bufsize / 4);
        for (;;) {
             if (!pcm->running) {
                  if (pcm_prepare(pcm)) {
                      fprintf(stderr, "Aplay:Failed in pcm_prepare\n");
                      pcm_close(pcm);
                      return -errno;
                  }
                  pcm->running = 1;
                  start = 0;
             }
             /* Sync the current Application pointer from the kernel */
             pcm->sync_ptr->flags = SNDRV_PCM_SYNC_PTR_APPL | SNDRV_PCM_SYNC_PTR_AVAIL_MIN;//SNDRV_PCM_SYNC_PTR_HWSYNC;
             err = sync_ptr(pcm);
             if (err == EPIPE) {
                 fprintf(stderr, "Aplay:Failed in sync_ptr \n");
                 /* we failed to make our window -- try to restart */
                 pcm->underruns++;
                 pcm->running = 0;
                 continue;
             }
             /*
              * Check for the available buffer in driver. If available buffer is
              * less than avail_min we need to wait
              */
             avail = pcm_avail(pcm);
             if (avail < 0) {
                 fprintf(stderr, "Aplay:Failed in pcm_avail\n");
                 pcm_close(pcm);
                 return avail;
             }
             if (avail < pcm->sw_p->avail_min) {
                 poll(pfd, nfds, TIMEOUT_INFINITE);
                 continue;
             }
             /*
              * Now that we have buffer size greater than avail_min available to
              * to be written we need to calcutate the buffer offset where we can
              * start writting.
              */
             dst_addr = dst_address(pcm);

             if (debug) {
                 fprintf(stderr, "dst_addr = 0x%08x\n", dst_addr);
                 fprintf(stderr, "Aplay:avail = %d frames = %d\n",avail, frames);
                 fprintf(stderr, "Aplay:sync_ptr->s.status.hw_ptr %ld  pcm->buffer_size %d  sync_ptr->c.control.appl_ptr %ld\n",
                            pcm->sync_ptr->s.status.hw_ptr,
                            pcm->buffer_size,
                            pcm->sync_ptr->c.control.appl_ptr);
             }

             /*
              * Read from the file to the destination buffer in kernel mmaped buffer
              * This reduces a extra copy of intermediate buffer.
              */
             memset(dst_addr, 0x0, bufsize);

             if (data_sz && !piped) {
                 if (remainingData < bufsize) {
                     bufsize = remainingData;
                     frames = (pcm->flags & PCM_MONO) ? (remainingData / 2) : (remainingData / 4);
                 }
             }

             err = read(fd, dst_addr , bufsize);
             if (debug)
                 fprintf(stderr, "read %d bytes from file\n", err);
             if (err <= 0)
                 break;

             if (data_sz && !piped) {
                 remainingData -= bufsize;
                 if (remainingData <= 0)
                     break;
             }

             /*
              * Increment the application pointer with data written to kernel.
              * Update kernel with the new sync pointer.
              */
             pcm->sync_ptr->c.control.appl_ptr += frames;
             pcm->sync_ptr->flags = 0;

             err = sync_ptr(pcm);
             if (err == EPIPE) {
                 fprintf(stderr, "Aplay:Failed in sync_ptr 2 \n");
                 /* we failed to make our window -- try to restart */
                 pcm->underruns++;
                 pcm->running = 0;
                 continue;
             }

             if (debug) {
                 fprintf(stderr, "Aplay:sync_ptr->s.status.hw_ptr %ld  sync_ptr->c.control.appl_ptr %ld\n",
                            pcm->sync_ptr->s.status.hw_ptr,
                            pcm->sync_ptr->c.control.appl_ptr);
#ifdef QCOM_COMPRESSED_AUDIO_ENABLED
                 if (compressed && start) {
                    struct snd_compr_tstamp tstamp;
		    if (ioctl(pcm->fd, SNDRV_COMPRESS_TSTAMP, &tstamp))
			fprintf(stderr, "Aplay: failed SNDRV_COMPRESS_TSTAMP\n");
                    else
	                fprintf(stderr, "timestamp = %lld\n", tstamp.timestamp);
		}
#endif
             }
             /*
              * If we have reached start threshold of buffer prefill,
              * its time to start the driver.
              */
                 if(start)
                     goto start_done;
                 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_START)) {
                     err = -errno;
                     if (errno == EPIPE) {
                         fprintf(stderr, "Aplay:Failed in SNDRV_PCM_IOCTL_START\n");
                         /* we failed to make our window -- try to restart */
                         pcm->underruns++;
                         pcm->running = 0;
                         continue;
                    } else {
                        fprintf(stderr, "Aplay:Error no %d \n", errno);
                        pcm_close(pcm);
                        return -errno;
                    }
                } else
                    start = 1;

start_done:
                offset += frames;
        }
        while(1) {
            pcm->sync_ptr->flags = SNDRV_PCM_SYNC_PTR_APPL | SNDRV_PCM_SYNC_PTR_AVAIL_MIN;//SNDRV_PCM_SYNC_PTR_HWSYNC;
            sync_ptr(pcm);
            /*
             * Check for the available buffer in driver. If available buffer is
             * less than avail_min we need to wait
             */
            if (pcm->sync_ptr->s.status.hw_ptr >= pcm->sync_ptr->c.control.appl_ptr) {
                fprintf(stderr, "Aplay:sync_ptr->s.status.hw_ptr %ld  sync_ptr->c.control.appl_ptr %ld\n",
                           pcm->sync_ptr->s.status.hw_ptr,
                           pcm->sync_ptr->c.control.appl_ptr);
                break;
            } else
                poll(pfd, nfds, TIMEOUT_INFINITE);
        }
    } else {
        if (pcm_prepare(pcm)) {
            fprintf(stderr, "Aplay:Failed in pcm_prepare\n");
            pcm_close(pcm);
            return -errno;
        }

        bufsize = pcm->period_size;

        data = calloc(1, bufsize);
        if (!data) {
            fprintf(stderr, "Aplay:could not allocate %d bytes\n", bufsize);
            pcm_close(pcm);
            return -ENOMEM;
        }

        if (data_sz && !piped) {
            if (remainingData < bufsize)
                bufsize = remainingData;
        }

        while (read(fd, data, bufsize) > 0) {
            if (pcm_write(pcm, data, bufsize)){
                fprintf(stderr, "Aplay: pcm_write failed\n");
                free(data);
                pcm_close(pcm);
                return -errno;
            }
            memset(data, 0, bufsize);

            if (data_sz && !piped) {
                remainingData -= bufsize;
                if (remainingData <= 0)
                    break;
                if (remainingData < bufsize)
                       bufsize = remainingData;
            }
        }
        free(data);
    }
    fprintf(stderr, "Aplay: Done playing\n");
    pcm_close(pcm);
    return 0;
}