예제 #1
0
static void *receive_thread(void *arg) {
    float isample;
    float qsample;
    int outsamples;
    int elements;
    int flags=0;
    long long timeNs=0;
    long timeoutUs=10000L;
    int i;
#ifdef TIMING
    struct timeval tv;
    long start_time, end_time;
    rate_samples=0;
    gettimeofday(&tv, NULL);
    start_time=tv.tv_usec + 1000000 * tv.tv_sec;
#endif
    running=1;
    fprintf(stderr,"lime_protocol: receive_thread\n");
    while(running) {
        elements=SoapySDRDevice_readStream(lime_device,stream,(void *)&buffer,max_samples,&flags,&timeNs,timeoutUs);
//fprintf(stderr,"read %d elements\n",elements);
        if(actual_rate!=sample_rate) {
            for(i=0; i<elements; i++) {
                resamples[i*2]=(double)buffer[i*2];
                resamples[(i*2)+1]=(double)buffer[(i*2)+1];
            }

            outsamples=xresample(resampler);

            for(i=0; i<outsamples; i++) {
                iqinputbuffer[samples*2]=(double)resampled[i*2];
                iqinputbuffer[(samples*2)+1]=(double)resampled[(i*2)+1];
                samples++;
#ifdef TIMING
                rate_samples++;
                if(rate_samples==sample_rate) {
                    gettimeofday(&tv, NULL);
                    end_time=tv.tv_usec + 1000000 * tv.tv_sec;
                    fprintf(stderr,"%d samples in %ld\n",rate_samples, end_time-start_time);
                    start_time=end_time;
                    rate_samples=0;
                }
#endif
                if(samples==buffer_size) {
                    int error;
                    fexchange0(CHANNEL_RX0, iqinputbuffer, audiooutputbuffer, &error);
                    if(error!=0) {
                        fprintf(stderr,"fexchange0 (CHANNEL_RX0) returned error: %d\n", error);
                    }

                    if(local_audio) {
                        audio_write(audiooutputbuffer,outputsamples);
                    }
                    Spectrum0(1, CHANNEL_RX0, 0, 0, iqinputbuffer);
                    samples=0;
                }
            }
        } else {
            for(i=0; i<elements; i++) {
                iqinputbuffer[samples*2]=(double)buffer[i*2];
                iqinputbuffer[(samples*2)+1]=(double)buffer[(i*2)+1];
                samples++;
                if(samples==buffer_size) {
                    int error;
                    fexchange0(CHANNEL_RX0, iqinputbuffer, audiooutputbuffer, &error);
                    if(error!=0) {
                        fprintf(stderr,"fexchange0 (CHANNEL_RX0) returned error: %d\n", error);
                    }

                    audio_write(audiooutputbuffer,outputsamples);
                    Spectrum0(1, CHANNEL_RX0, 0, 0, iqinputbuffer);
                    samples=0;
                }
            }
        }
    }

    fprintf(stderr,"lime_protocol: receive_thread: SoapySDRDevice_closeStream\n");
    SoapySDRDevice_closeStream(lime_device,stream);
    fprintf(stderr,"lime_protocol: receive_thread: SoapySDRDevice_unmake\n");
    SoapySDRDevice_unmake(lime_device);

}
예제 #2
0
void* new_protocol_thread(void* arg) {

    DISCOVERED* d=&discovered[selected_device];

    struct sockaddr_in addr;
    int length;
    unsigned char buffer[2048];
    int bytesread;
    short sourceport;

    long sequence;
    long long timestamp;
    int bitspersample;
    int samplesperframe;

    int b;
    int leftsample;
    int rightsample;
    float leftsamplefloat;
    float rightsamplefloat;

    int previous_ptt;
    int previous_dot;
    int previous_dash;

    int samples;
    //float leftinputbuffer[BUFFER_SIZE];
    //float rightinputbuffer[BUFFER_SIZE];
    double iqinputbuffer[BUFFER_SIZE*2];

    int outputsamples;
    //float leftoutputbuffer[BUFFER_SIZE];
    //float rightoutputbuffer[BUFFER_SIZE];
    double audiooutputbuffer[BUFFER_SIZE*2];

    short leftaudiosample;
    short rightaudiosample;
    long audiosequence;
    unsigned char audiobuffer[1444];
    int audioindex;

    int micsample;
    float micsamplefloat;

    int micsamples;
    /*
        float micleftinputbuffer[BUFFER_SIZE];  // 48000
        float micrightinputbuffer[BUFFER_SIZE];
    */
    double micinputbuffer[BUFFER_SIZE*2];

    int micoutputsamples;
    /*
        float micleftoutputbuffer[BUFFER_SIZE*4]; // 192000
        float micrightoutputbuffer[BUFFER_SIZE*4];
    */
    double micoutputbuffer[BUFFER_SIZE*4*2];

    double gain;

    int isample;
    int qsample;
    long tx_iq_sequence;
    unsigned char iqbuffer[1444];
    int iqindex;

    int i, j;
    fprintf(stderr,"new_protocol_thread: receiver=%d\n", receiver);

    micsamples=0;
    iqindex=4;

    switch(sample_rate) {
    case 48000:
        outputsamples=BUFFER_SIZE;
        break;
    case 96000:
        outputsamples=BUFFER_SIZE/2;
        break;
    case 192000:
        outputsamples=BUFFER_SIZE/4;
        break;
    case 384000:
        outputsamples=BUFFER_SIZE/8;
        break;
    case 768000:
        outputsamples=BUFFER_SIZE/16;
        break;
    case 1536000:
        outputsamples=BUFFER_SIZE/32;
        break;
    }

    micoutputsamples=BUFFER_SIZE*4;  // 48000 in, 192000 out

    fprintf(stderr,"outputsamples=%d\n", outputsamples);
    data_socket=socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP);
    if(data_socket<0) {
        fprintf(stderr,"metis: create socket failed for data_socket: receiver=%d\n",receiver);
        exit(-1);
    }

    int optval = 1;
    setsockopt(data_socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));

    // bind to the interface
    if(bind(data_socket,(struct sockaddr*)&d->interface_address,d->interface_length)<0) {
        fprintf(stderr,"metis: bind socket failed for data_socket: receiver=%d\n",receiver);
        exit(-1);
    }

    memcpy(&base_addr,&d->address,d->address_length);
    base_addr_length=d->address_length;
    base_addr.sin_port=htons(GENERAL_REGISTERS_FROM_HOST_PORT);

    memcpy(&receiver_addr,&d->address,d->address_length);
    receiver_addr_length=d->address_length;
    receiver_addr.sin_port=htons(RECEIVER_SPECIFIC_REGISTERS_FROM_HOST_PORT);

    memcpy(&transmitter_addr,&d->address,d->address_length);
    transmitter_addr_length=d->address_length;
    transmitter_addr.sin_port=htons(TRANSMITTER_SPECIFIC_REGISTERS_FROM_HOST_PORT);

    memcpy(&high_priority_addr,&d->address,d->address_length);
    high_priority_addr_length=d->address_length;
    high_priority_addr.sin_port=htons(HIGH_PRIORITY_FROM_HOST_PORT);

    memcpy(&audio_addr,&d->address,d->address_length);
    audio_addr_length=d->address_length;
    audio_addr.sin_port=htons(AUDIO_FROM_HOST_PORT);

    memcpy(&iq_addr,&d->address,d->address_length);
    iq_addr_length=d->address_length;
    iq_addr.sin_port=htons(TX_IQ_FROM_HOST_PORT);

    memcpy(&data_addr,&d->address,d->address_length);
    data_addr_length=d->address_length;
    data_addr.sin_port=htons(RX_IQ_TO_HOST_PORT+receiver);

    samples=0;
    audioindex=4; // leave space for sequence
    audiosequence=0L;

    new_protocol_general();
    new_protocol_start();
    new_protocol_high_priority(1,0,drive);

    while(running) {
        bytesread=recvfrom(data_socket,buffer,sizeof(buffer),0,(struct sockaddr*)&addr,&length);
        if(bytesread<0) {
            fprintf(stderr,"recvfrom socket failed for new_protocol_thread: receiver=%d", receiver);
            exit(1);
        }

        short sourceport=ntohs(addr.sin_port);

//fprintf(stderr,"received packet length %d from port %d\n",bytesread,sourceport);

        if(sourceport==RX_IQ_TO_HOST_PORT) {

            sequence=((buffer[0]&0xFF)<<24)+((buffer[1]&0xFF)<<16)+((buffer[2]&0xFF)<<8)+(buffer[3]&0xFF);
            timestamp=((long long)(buffer[4]&0xFF)<<56)+((long long)(buffer[5]&0xFF)<<48)+((long long)(buffer[6]&0xFF)<<40)+((long long)(buffer[7]&0xFF)<<32);
            ((long long)(buffer[8]&0xFF)<<24)+((long long)(buffer[9]&0xFF)<<16)+((long long)(buffer[10]&0xFF)<<8)+(long long)(buffer[11]&0xFF);
            bitspersample=((buffer[12]&0xFF)<<8)+(buffer[13]&0xFF);
            samplesperframe=((buffer[14]&0xFF)<<8)+(buffer[15]&0xFF);

//fprintf(stderr,"samples per frame %d\n",samplesperframe);

            if(!isTransmitting()) {
                b=16;
                for(i=0; i<samplesperframe; i++) {
                    leftsample   = (int)((signed char) buffer[b++]) << 16;
                    leftsample  += (int)((unsigned char)buffer[b++]) << 8;
                    leftsample  += (int)((unsigned char)buffer[b++]);
                    rightsample  = (int)((signed char) buffer[b++]) << 16;
                    rightsample += (int)((unsigned char)buffer[b++]) << 8;
                    rightsample += (int)((unsigned char)buffer[b++]);

                    leftsamplefloat=(float)leftsample/8388607.0; // for 24 bits
                    rightsamplefloat=(float)rightsample/8388607.0; // for 24 bits

                    //leftinputbuffer[samples]=leftsamplefloat;
                    //rightinputbuffer[samples]=rightsamplefloat;
                    iqinputbuffer[samples*2]=(double)leftsamplefloat;
                    iqinputbuffer[(samples*2)+1]=(double)rightsamplefloat;

                    samples++;
                    if(samples==BUFFER_SIZE) {
                        int error;
                        fexchange0(CHANNEL_RX0+receiver, iqinputbuffer, audiooutputbuffer, &error);
                        if(error!=0) {
                            fprintf(stderr,"fexchange0 returned error: %d for receiver %d\n", error,receiver);
                        }

                        Spectrum0(1, CHANNEL_RX0+receiver, 0, 0, iqinputbuffer);

                        for(j=0; j<outputsamples; j++) {
                            leftaudiosample=(short)(audiooutputbuffer[j*2]*32767.0*volume);
                            rightaudiosample=(short)(audiooutputbuffer[(j*2)+1]*32767.0*volume);

                            audiobuffer[audioindex++]=leftaudiosample>>8;
                            audiobuffer[audioindex++]=leftaudiosample;
                            audiobuffer[audioindex++]=rightaudiosample>>8;
                            audiobuffer[audioindex++]=rightaudiosample;

                            if(audioindex>=sizeof(audiobuffer)) {
                                // insert the sequence
                                audiobuffer[0]=audiosequence>>24;
                                audiobuffer[1]=audiosequence>>16;
                                audiobuffer[2]=audiosequence>>8;
                                audiobuffer[3]=audiosequence;
                                // send the buffer
                                if(sendto(data_socket,audiobuffer,sizeof(audiobuffer),0,(struct sockaddr*)&audio_addr,audio_addr_length)<0) {
                                    fprintf(stderr,"sendto socket failed for audio\n");
                                    exit(1);
                                }
                                audioindex=4;
                                audiosequence++;
                            }
                        }
                        samples=0;
                    }
                }