コード例 #1
0
/**
 * Set up capture based on the audio sample waverec except we use VoIP parameters
 */
static int capture(circular_buffer_t* circular_buffer) {
	// Re-usable buffer for capture
	char *record_buffer;
	record_buffer = (char*) malloc(g_frame_size_c);

	// Some diagnostic variables
	int failed = 0;
	int totalRead = 0;
	snd_pcm_channel_status_t status;
	status.channel = SND_PCM_CHANNEL_CAPTURE;

	// Loop until stopAudio() flags us
	while (g_execute_audio) {
		// This blocking read appears to take much longer than 20ms on the simulator
		// but it never fails and always returns 160 bytes
		int read = snd_pcm_plugin_read(g_pcm_handle_c, record_buffer,
				g_frame_size_c);
		if (read < 0 || read != g_frame_size_c) {
			failed++;
			fprintf(stderr,"CAPTURE FAILURE: snd_pcm_plugin_read: %d requested = %d\n",read,g_frame_size_c);
			if (snd_pcm_plugin_status(g_pcm_handle_c, &status) < 0) {
				fprintf(stderr, "Capture channel status error: %d\n",status.status);
			} else {
				if (status.status == SND_PCM_STATUS_READY
				|| status.status == SND_PCM_STATUS_OVERRUN
				|| status.status == SND_PCM_STATUS_CHANGE
				|| status.status == SND_PCM_STATUS_ERROR) {
					fprintf(stderr, "CAPTURE FAILURE:snd_pcm_plugin_status: = %d \n",status.status);
					if (snd_pcm_plugin_prepare (g_pcm_handle_c, SND_PCM_CHANNEL_CAPTURE) < 0) {
						fprintf (stderr, "Capture channel prepare error 1 %d\n",status.status);
						exit (1);
					}

				}
			}
		} else {
			totalRead += read;
			// On simulator always room in the circular buffer
			if (!writeToCircularBuffer(circular_buffer, record_buffer,
					g_frame_size_c)) {
				failed++;
			}
		}
		capture_ready = true;

	}
	fprintf(stderr,"CAPTURE EXIT BEGIN\n");
	(void) snd_pcm_plugin_flush(g_pcm_handle_c, SND_PCM_CHANNEL_CAPTURE);
	//(void)snd_mixer_close (mixer_handle);
	(void) snd_pcm_close(g_pcm_handle_c);
	audio_manager_free_handle(g_audio_manager_handle_c);
	// IMPORTANT NB: You only get failed on capture if the play loop has exited hence the circular buffer fills. This is with the simulator
	fprintf(stderr, "CAPTURE EXIT Total Bytes read = %d failed = %d\n",totalRead,failed);
	free(record_buffer);
	return 0;
}
コード例 #2
0
qint64 QnxAudioInput::read(char *data, qint64 len)
{
    int errorCode = 0;
    QByteArray tempBuffer(m_periodSize, 0);

    const int actualRead = snd_pcm_plugin_read(m_pcmHandle, tempBuffer.data(), m_periodSize);
    if (actualRead < 1) {
        snd_pcm_channel_status_t status;
        memset(&status, 0, sizeof(status));
        status.channel = SND_PCM_CHANNEL_CAPTURE;
        if ((errorCode = snd_pcm_plugin_status(m_pcmHandle, &status)) < 0) {
            qWarning("QnxAudioInput: read error, couldn't get plugin status (0x%x)", -errorCode);
            close();
            setError(QAudio::FatalError);
            setState(QAudio::StoppedState);
            return -1;
        }

        if (status.status == SND_PCM_STATUS_READY
            || status.status == SND_PCM_STATUS_OVERRUN) {
            if ((errorCode = snd_pcm_plugin_prepare(m_pcmHandle, SND_PCM_CHANNEL_CAPTURE)) < 0) {
                qWarning("QnxAudioInput: read error, couldn't prepare plugin (0x%x)", -errorCode);
                close();
                setError(QAudio::FatalError);
                setState(QAudio::StoppedState);
                return -1;
            }
        }
    } else {
        setError(QAudio::NoError);
        setState(QAudio::ActiveState);
    }

    if (m_volume < 1.0f)
        QAudioHelperInternal::qMultiplySamples(m_volume, m_format, tempBuffer.data(), tempBuffer.data(), actualRead);

    m_bytesRead += actualRead;

    if (m_pullMode) {
        m_audioSource->write(tempBuffer.data(), actualRead);
    } else {
        memcpy(data, tempBuffer.data(), qMin(static_cast<qint64>(actualRead), len));
    }

    m_bytesAvailable = 0;

    return actualRead;
}
コード例 #3
0
static int process_read(snd_pcm_t* hRecord)
{
    int nread = snd_pcm_plugin_read(hRecord, outputdata, (size_t)fragsize);
    if (nread != fragsize) {
         cli_print("snd_pcm_plugin_read: %s", snd_strerror(nread));
         return 1;
    } else {
        if (fwrite((void*)outputdata, (size_t)1, (size_t)nread, outputfile) != (size_t)nread) {
            cli_print("fwrite: %s", strerror(errno));
            return 1;
        } else {
            outputdatasize += nread;
        }
    }
    return 0;
}
コード例 #4
0
ファイル: bb10_dev.c プロジェクト: KevinHM/pjsip
static int ca_thread_func (void *arg)
{
    struct bb10_stream* stream = (struct bb10_stream *) arg;
    int size                   = stream->ca_buf_size;
    unsigned long nframes      = stream->ca_frames;
    void *user_data            = stream->user_data;
    /* Buffer to fill for PJMEDIA */
    char *buf 		       = stream->ca_buf;
    pj_timestamp tstamp;
    int result;
    int policy;
    struct sched_param param;

    TRACE_((THIS_FILE, "ca_thread_func: size = %d ", size));

    if (pthread_getschedparam(pthread_self(), &policy, &param) == 0) {
	param.sched_priority = 18;
	pthread_setschedparam (pthread_self(), policy, &param);
    }

    pj_bzero (buf, size);
    tstamp.u64 = 0;

    /* Final init now the thread has started */
    if ((result = snd_pcm_plugin_prepare (stream->ca_pcm,
                                          SND_PCM_CHANNEL_CAPTURE)) < 0)
    {
        TRACE_((THIS_FILE, "ca_thread_func failed prepare = %d", result));
        return PJ_SUCCESS;
    }

    while (!stream->quit) {
        pjmedia_frame frame;

        //pj_bzero (buf, size);

        /* read the input device */
        result = snd_pcm_plugin_read(stream->ca_pcm, buf,size);
        if(result <0 || result != size) {
            /* We expect result to be size (640)
             * It's not so we have to read the status error and "prepare"
             * the channel. This usually happens when output audio routing
             * has been changed by another thread.
             * We won't "continue", instead just do what we can and leave
             * the end of the loop to write what's in the buffer. Not entirely
             * correct but saves a potential underrun in PJMEDIA
             */
            PJ_LOG (4,(THIS_FILE,
        	       "snd_pcm_plugin_read ERROR read = %d required = %d",
        	       result,size));
            snd_pcm_channel_status_t status;
            status.channel = SND_PCM_CHANNEL_CAPTURE;
            if ((result = snd_pcm_plugin_status (stream->ca_pcm, &status)) < 0)
            {
        	/* Should not fail but all we can do is continue */
        	PJ_LOG(4,(THIS_FILE, "capture: snd_pcm_plugin_status ret = %d",
        		  result));
            } else {
        	/* RIM say these are the errors that we should "prepare"
        	 * after */
        	if (status.status == SND_PCM_STATUS_READY ||
        		status.status == SND_PCM_STATUS_OVERRUN ||
        		status.status == SND_PCM_STATUS_ERROR)
        	{
        	    if (snd_pcm_plugin_prepare (stream->ca_pcm,
        	                                SND_PCM_CHANNEL_CAPTURE) < 0)
        	    {
        		PJ_LOG (4,(THIS_FILE,
        			   "overrun: capture channel prepare  error"));
        	    }
        	}
            }
        }

        if (stream->quit)
            break;

        /* Write the capture audio data to PJMEDIA */
        frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
        frame.buf = (void *) buf;
        frame.size = size;
        frame.timestamp.u64 = tstamp.u64;
        frame.bit_info = 0;

        result = stream->ca_cb (user_data, &frame);
        if (result != PJ_SUCCESS || stream->quit)
            break;

        tstamp.u64 += nframes;
    }

    flush_capture(stream);
    TRACE_((THIS_FILE, "ca_thread_func: Stopped"));

    return PJ_SUCCESS;
}
コード例 #5
0
ファイル: qsa.c プロジェクト: Sponk/NeoEditor
static ALCenum qsa_capture_samples(ALCdevice *device, ALCvoid *buffer, ALCuint samples)
{
    qsa_data* data=(qsa_data*)device->ExtraData;
    char* read_ptr;
    snd_pcm_channel_status_t status;
    fd_set rfds;
    int selectret;
    struct timeval timeout;
    int bytes_read;
    ALint frame_size=FrameSizeFromDevFmt(device->FmtChans, device->FmtType);
    ALint len=samples*frame_size;
    int rstatus;

    read_ptr=buffer;

    while (len>0)
    {
        FD_ZERO(&rfds);
        FD_SET(data->audio_fd, &rfds);
        timeout.tv_sec=2;
        timeout.tv_usec=0;

        /* Select also works like time slice to OS */
        bytes_read=0;
        selectret=select(data->audio_fd+1, &rfds, NULL, NULL, &timeout);
        switch (selectret)
        {
            case -1:
                 aluHandleDisconnect(device);
                 return ALC_INVALID_DEVICE;
            case 0:
                 break;
            default:
                 if (FD_ISSET(data->audio_fd, &rfds))
                 {
                     bytes_read=snd_pcm_plugin_read(data->pcmHandle, read_ptr, len);
                     break;
                 }
                 break;
        }

        if (bytes_read<=0)
        {
            if ((errno==EAGAIN) || (errno==EWOULDBLOCK))
            {
                continue;
            }

            memset(&status, 0, sizeof (status));
            status.channel=SND_PCM_CHANNEL_CAPTURE;
            snd_pcm_plugin_status(data->pcmHandle, &status);

            /* we need to reinitialize the sound channel if we've overrun the buffer */
            if ((status.status==SND_PCM_STATUS_OVERRUN) ||
                (status.status==SND_PCM_STATUS_READY))
            {
                if ((rstatus=snd_pcm_plugin_prepare(data->pcmHandle, SND_PCM_CHANNEL_CAPTURE))<0)
                {
                    ERR("capture prepare failed: %s\n", snd_strerror(rstatus));
                    aluHandleDisconnect(device);
                    return ALC_INVALID_DEVICE;
                }
                snd_pcm_capture_go(data->pcmHandle);
            }
        }
        else
        {
            read_ptr+=bytes_read;
            len-=bytes_read;
        }
    }

    return ALC_NO_ERROR;
}
コード例 #6
0
ファイル: bb10_dev.c プロジェクト: iTeach/SipClient
static int ca_thread_func (void *arg)
{
    struct bb10_stream* stream = (struct bb10_stream *) arg;
    int size                   = stream->ca_buf_size;
    unsigned long nframes      = stream->ca_frames;
    void *user_data            = stream->user_data;
    /* Buffer to fill for PJMEDIA */
    char *buf 		       = stream->ca_buf;
    pj_timestamp tstamp;
    int result;
    struct sched_param param;
    pthread_t *thid;

    TRACE_((THIS_FILE, "ca_thread_func: size = %d ", size));

    thid = (pthread_t*) pj_thread_get_os_handle (pj_thread_this());
    param.sched_priority = sched_get_priority_max (SCHED_RR);

    result = pthread_setschedparam (*thid, SCHED_RR, &param);
    if (result) {
        if (result == EPERM) {
            PJ_LOG (4,(THIS_FILE, "Unable to increase thread priority, "
                                  "root access needed."));
        } else {
            PJ_LOG (4,(THIS_FILE, "Unable to increase thread priority, "
                                  "error: %d", result));
        }
    }

    pj_bzero (buf, size);
    tstamp.u64 = 0;

    /* Final init now the thread has started */
    if ((result = snd_pcm_plugin_prepare (stream->ca_pcm,
                                          SND_PCM_CHANNEL_CAPTURE)) < 0)
    {
        close_capture_pcm(stream);
        TRACE_((THIS_FILE, "ca_thread_func failed prepare = %d", result));
	return PJ_SUCCESS;
    }

    while (!stream->quit) {
        pjmedia_frame frame;

        pj_bzero (buf, size);

        result = snd_pcm_plugin_read(stream->ca_pcm, buf,size);
        if(result <0 || result != size) {
            snd_pcm_channel_status_t status;
            if (snd_pcm_plugin_status (stream->ca_pcm, &status) < 0) {
                PJ_LOG (4,(THIS_FILE, "overrun: capture channel status "
                                      "error"));
                continue;
            }

            if (status.status == SND_PCM_STATUS_READY ||
        	status.status == SND_PCM_STATUS_OVERRUN) {
                if (snd_pcm_plugin_prepare (stream->ca_pcm,
                                            SND_PCM_CHANNEL_CAPTURE) < 0)
                {
                    PJ_LOG (4,(THIS_FILE, "overrun: capture channel prepare  "
                                          "error"));
                    continue;
                }
            }
        }

        if (stream->quit)
            break;

        frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
        frame.buf = (void *) buf;
        frame.size = size;
        frame.timestamp.u64 = tstamp.u64;
        frame.bit_info = 0;

        result = stream->ca_cb (user_data, &frame);
        if (result != PJ_SUCCESS || stream->quit)
            break;

        tstamp.u64 += nframes;
    }

    flush_capture(stream);
    close_capture_pcm(stream);
    TRACE_((THIS_FILE, "ca_thread_func: Stopped"));

    return PJ_SUCCESS;
}