void *melp_rec(void) { int length, frame,count, melp_file_count; int eof_reached = 0; //int num_frames = 0; //short speech_in[11]; short speech_out[FRM]; unsigned char enc_speech[11]; FILE *fp_in, *fp_out; melpe_i(); melp_file_count = 0; printf("\n1.2 kb/s Proposed Federal Standard MELP speech coder by Jawad\n"); printf(" C simulation, version 1.0\n\n"); while (1) { sem_wait(&melp_start); melp_file_count = melp_file_count + 1; if(melp_file_count % 2 == 1) { fp_in = fopen("out1.bit" ,"rb"); fp_out = fopen("record0.raw","wb"); } else { fp_in = fopen("out2.bit" ,"rb"); fp_out = fopen("record1.raw","wb"); } eof_reached = 0; while (eof_reached == 0) { length = fread(&enc_speech,sizeof(char),11,fp_in); melpe_s(speech_out, enc_speech); fwrite(speech_out,sizeof(short),FRM,fp_out); ///if (length < FRAME) if (length < 11) { eof_reached = 1; printf("eof reached \n"); } } fclose(fp_in); fclose(fp_out); eof_reached = 0; sem_post(&play_start); } pthread_exit(NULL); }
//***************************************************************************** //receiving loop: grab 48KHz baseband samples from Line, //demodulate, decrypt, decode, play 8KHz voice over Speaker int rx(int typing) { //input: -1 for no typing chars, 1 - exist some chars in input buffer //output: 0 - no any jobs doing, 1 - some jobs were doing int i; float f; int job=0; //flag of any job were doing char lag_flag=0; //block lag is locked (modems synchronization complete) //char lock_flag=0; //phase of carrier (1333Hz, 6 samples per period) is locked //char sync_flag=0; //the difference of frequency transmitter-to-receiver sampling rate is locked //char current_lag=0; //block lag (0-90, aligned to last bit position, the 6 samples for bit) char info[8]={0}; //call info //regularly play Speaker's buffer job=playjit(); //the first try to play a tail of samples in buffer //check for we have enough samples for demodulation if(cnt<180*6) //check we haven't enough of unprocessed samples { //move tail to start of receiving buffer if(samples>speech) //check for tail { for(i=0; i<cnt; i++) speech[i]=samples[i]; //move tail to start of buffer samples=speech; //set pointer to start of buffer } //record i=_soundgrab((char*)(samples+cnt), 180*6); //try to grab new 48KHZ samples from Line if((i>0)&&(i<=(180*6))) //some samples grabbed { cnt+=i; //add grabbed samples to account job+=4; //set job } } else //we have enough samples for processing { i=Demodulate(samples, buf); //process samples: 36*6 (35-37)*6 samples samples+=i; //move pointer to next samples (with frequency adjusting) cnt-=i; //decrease the number of unprocessed samples if(0x80&buf[11]) //checks flag for output data block is ready { //check for synck and averages BER lag_flag=!(!(buf[11]&0x40)); //block lag is locked (synchronization compleet) //lock_flag=!(!(buf[11]&0x20)); //phaze of carrier (1333Hz, 6 samples per period) is locked //sync_flag=!(!(buf[11]&0x10)); //the differency of frequency transmitter-to-receiver sampling rate is locked //current_lag=buf[10]>>1; //block lag (0-90, aligned to last bit position, the 6 samples for bit) if(lag_flag) //check modem sync { //averages BER i=(0x0F&buf[11]); //count symbols errors (only 1 error per 9-bit symbol can be detected) fber*=0.99; //fber in range 0-900 fber+=i; //in range 0-9 errored bits per 90 bits treceived } //output statistics if(typing<0) //output call's info if no characters were typed by user { f=Mute(0); //get packets counter value i=State(0); //get current connection step * vad flag //notification of state and voice output if(!i) strcpy(info, (char*)"IDLE"); else if(abs(i)<8) strcpy(info, (char*)"CALL"); else if(f<=0) strcpy(info, (char*)"MUTE"); else if(i<0) strcpy(info, (char*)"PAUS"); else strcpy(info, (char*)"TALK"); if(f<0) f=-f; //absolute value i=f*0.0675; //computes total time of the call in sec: each packet 67,5 ms f=fau/4-100; //computes authentification level in % if(f<0) f=0; //only positive results have reason //current state notification if(lag_flag) printf("%s %dmin %dsec BER:%0.02f AU:%d%%\r", info, i/60, i%60, fber/90, (int)f); else printf("%s %dmin %dsec BER:---- AU:%d%%\r", info, i/60, i%60, (int)f); //lost of sync in modem } //process received packet detects voice/silence type buf[11]=0xFE; //set flag default as for silence descriptor if(lag_flag) //check modem sync { i=ProcessPkt(buf); //decode received packet if(i>=0) //received packet is a control type { fau*=0.99; //fau in range 0-800 (400 for random data) fau+=i; //averages authentication level } else if(i==-3) { buf[11]=0xFF; //set flag for voice data received } } //end of sync ok, packets processing } //end of data block received } //end of a portion of sampless processing //check we have received data and output buffer is empty for decoding if((0x0E&buf[11])&&(l_jit_buf<=180)) { //decode voice data or set silency job+=16; //set job if(1&buf[11]) //this is a voice frame, decode it { melpe_s(sp, buf); //decode 81 bits in 11 bytes to 540 8KHz samples } else memset(sp, 0, 1080); //or output 67.5 mS of silence buf[11]=0; //clears flag: data buffer is processed //computes average playing delay i=getdelay()+l_jit_buf; //total number of unplayed samples in buffers fdelay*=0.9; //averages fdelay+=i; //computes optimal resapling ratio for the optimum delay f=fabs(fdelay/10-720)/10000000; //correction rate due inconsistency if(i<360) qff-=f; //adjust current ratio else if(i>1080) qff+=f; if(qff<0.888) qff=0.888; //restrictions else if(qff>1.142) qff=1.142; //resample and play to Headset if(l_jit_buf>180) l_jit_buf=0; //prevent overflow l_jit_buf+=resample(sp, jit_buf+l_jit_buf, qff); //resample buffer for playing playjit(); //immediately try to play buffer } return job; }