Пример #1
0
static void sco_close_output_stream(struct audio_hw_device *dev,
					struct audio_stream_out *stream_out)
{
	struct sco_dev *sco_dev = (struct sco_dev *) dev;
	struct sco_stream_out *out = (struct sco_stream_out *) stream_out;

	DBG("dev %p stream %p fd %d", dev, stream_out, sco_dev->out->fd);

	if (sco_dev->out && sco_dev->out->fd) {
		close(sco_dev->out->fd);
		sco_dev->out->fd = -1;
	}

	if (out->resampler)
		release_resampler(out->resampler);

	free(out->downmix_buf);
	free(out);
	sco_dev->out = NULL;
}
Пример #2
0
//This is the rx samples forwarding thread (private)
void *usrp_rx_forwarder_thread (void *param)
{
    RECEIVER *pRec = (RECEIVER *)param; 
    int old_state, old_type;

    //debug
	//std::cerr << inspect_receiver(pRec) << std::endl;
    
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,&old_state);
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,&old_type);  
    RECEIVER_CYCLE = true;

    pRec->samples = 0;
    
    std::vector<std::complex<float> > *buff;
    QUEUE_BUFFER_ENTRY *item;
    
    //NEW RES LIB    
    int resampler_id = resampler_setup_new(MAX_USRP_RX_BUFFER, DECIM_RX, INTERP_RX);    
    
    if (resampler_id < 0) { //FAILURE!
        std::cerr << "RX Resampler object definition failed. Exiting..." << std::endl;
        exit (1);
    }
    std::cerr << boost::format("RX thread Using resampler %d.") % resampler_id << std::endl;
    
    
    std::cerr << "Starting the RX Data forwarding thread cycle" << std::endl;              
    
    while(1) {
    
        pthread_mutex_lock(&RECEIVER_CYCLE_lock); 
        bool do_cycle = RECEIVER_CYCLE;
        pthread_mutex_unlock(&RECEIVER_CYCLE_lock); 
        if (! do_cycle) break;
        
        //Extract from queue
        //If there is Vector buffer in the queue
        pthread_mutex_lock(&rx_queue_lock);            
        item = TAILQ_FIRST(&rx_samples_iq_stream);                   
        if (item != NULL) {            
            //Take next Vector buffer from the queue
            buff = (std::vector<std::complex<float> > *)item->data;              
            TAILQ_REMOVE(&rx_samples_iq_stream, item, entries);                    
            rx_queue_length--;
            pthread_mutex_unlock(&rx_queue_lock);
        } else {
            pthread_mutex_unlock(&rx_queue_lock);
            usleep(QUEUE_WAIT_TIME);
            continue;
        }  
        
        //RX path is disabled: skip the rest
        if (drop_rx_samples) {
            //Vector cleanup        
            delete buff;
            free(item);            
            continue;
        }           

        size_t num_rx_samps = buff->size();
        
        //Rational resampling is applied at this point
        //Interleaving real/imag in the resampler buffer        
        if (real_position == 1) {
            unsigned int i;            
        #pragma omp parallel for schedule(static) private(i)
            for (i=0; i<num_rx_samps; ++i)
                resampler_load_data(resampler_id, i, (*buff)[i].imag(), (*buff)[i].real());                        
        } else {
            unsigned int i;
        #pragma omp parallel for schedule(static) private(i)
            for (i=0; i<num_rx_samps; ++i)
                resampler_load_data(resampler_id, i, (*buff)[i].real(), (*buff)[i].imag());                                    
        }
        
        //Vector cleanup        
        delete buff;
        free(item);
                         
        //Rational resampling API here                
        char *rr_msg = NULL;
        int output_frames_gen = 0;
        int rr_retcode = do_resample(resampler_id, num_rx_samps, &output_frames_gen, rr_msg);         
                
        //std::cerr << boost::format("output_frames_gen %d.") % output_frames_gen << std::endl;                 
        
        //TIME BECHMARKING
        //gettimeofday(tod1, NULL);
        //std::cerr << boost::format("After resampler: %d |") % (tod1->tv_usec - tod->tv_usec);        
        
        if (rr_retcode == RRESAMPLER_NO_ERROR) { 
            //Fetch resampled data into the Receiver input buffer
            for (int j=0; j<output_frames_gen ; ++j) {                                                                           

                resampler_fetch_data(resampler_id, j, &pRec->input_buffer[pRec->samples], 
                                       &pRec->input_buffer[pRec->samples+RECEIVE_BUFFER_SIZE]);
                 
                pRec->samples++;

                if(pRec->samples==RECEIVE_BUFFER_SIZE) {                                        
                    
                    //send I/Q data to client
                    //std::cerr << boost::format("%s: sending data.") % __FUNCTION__ << std::endl;
                    send_IQ_buffer(pRec);
                    pRec->samples=0;                    
                }
            }
            
        } else {
            //A rational resampler error occurred!            
            std::cerr << boost::format("RX Rational resampling error: %s") % rr_msg << std::endl;
        }        
    }
    release_resampler(resampler_id);
    fprintf(stderr,"Exiting from USRP RX Forwarder thread\n");
    
    return NULL;

}
Пример #3
0
static int sco_open_output_stream(struct audio_hw_device *dev,
					audio_io_handle_t handle,
					audio_devices_t devices,
					audio_output_flags_t flags,
					struct audio_config *config,
					struct audio_stream_out **stream_out)
{
	struct sco_dev *adev = (struct sco_dev *) dev;
	struct sco_stream_out *out;
	int fd = -1;
	int chan_num, ret;
	size_t resample_size;
	uint16_t mtu;

	DBG("");

	if (ipc_connect_sco(&fd, &mtu) != SCO_STATUS_SUCCESS) {
		error("sco: cannot get fd");
		return -EIO;
	}

	DBG("got sco fd %d mtu %u", fd, mtu);

	out = calloc(1, sizeof(struct sco_stream_out));
	if (!out)
		return -ENOMEM;

	out->stream.common.get_sample_rate = out_get_sample_rate;
	out->stream.common.set_sample_rate = out_set_sample_rate;
	out->stream.common.get_buffer_size = out_get_buffer_size;
	out->stream.common.get_channels = out_get_channels;
	out->stream.common.get_format = out_get_format;
	out->stream.common.set_format = out_set_format;
	out->stream.common.standby = out_standby;
	out->stream.common.dump = out_dump;
	out->stream.common.set_parameters = out_set_parameters;
	out->stream.common.get_parameters = out_get_parameters;
	out->stream.common.add_audio_effect = out_add_audio_effect;
	out->stream.common.remove_audio_effect = out_remove_audio_effect;
	out->stream.get_latency = out_get_latency;
	out->stream.set_volume = out_set_volume;
	out->stream.write = out_write;
	out->stream.get_render_position = out_get_render_position;

	/* Configuration for Android */
	out->cfg.format = AUDIO_STREAM_DEFAULT_FORMAT;
	out->cfg.channels = AUDIO_CHANNEL_OUT_STEREO;
	out->cfg.rate = AUDIO_STREAM_DEFAULT_RATE;
	out->cfg.frame_num = OUT_STREAM_FRAMES;
	out->cfg.mtu = mtu;

	out->downmix_buf = malloc(out_get_buffer_size(&out->stream.common));
	if (!out->downmix_buf) {
		free(out);
		return -ENOMEM;
	}

	DBG("size %zd", out_get_buffer_size(&out->stream.common));

	/* Channel numbers for resampler */
	chan_num = 1;

	ret = create_resampler(out->cfg.rate, AUDIO_STREAM_SCO_RATE, chan_num,
						RESAMPLER_QUALITY_DEFAULT, NULL,
						&out->resampler);
	if (ret) {
		error("Failed to create resampler (%s)", strerror(ret));
		goto failed;
	}

	DBG("Created resampler: input rate [%d] output rate [%d] channels [%d]",
				out->cfg.rate, AUDIO_STREAM_SCO_RATE, chan_num);

	out->resample_frame_num = get_resample_frame_num(AUDIO_STREAM_SCO_RATE,
							out->cfg.rate,
							out->cfg.frame_num, 1);

	if (!out->resample_frame_num) {
		error("frame num is too small to resample, discard it");
		goto failed;
	}

	resample_size = sizeof(int16_t) * chan_num * out->resample_frame_num;

	out->resample_buf = malloc(resample_size);
	if (!out->resample_buf) {
		error("failed to allocate resample buffer for %u frames",
						out->resample_frame_num);
		goto failed;
	}

	DBG("resampler: frame num %u buf size %zd bytes",
					out->resample_frame_num, resample_size);

	*stream_out = &out->stream;
	adev->out = out;
	out->fd = fd;

	return 0;
failed:
	if (out->resampler)
		release_resampler(out->resampler);

	free(out->downmix_buf);
	free(out);
	stream_out = NULL;
	adev->out = NULL;

	return ret;
}