sample ComplexODF::process_frame(int signal_size, sample* signal) { sample phase_prediction; fftw_complex prediction; sample sum = 0.0; // do a FFT of the current frame memcpy(in, &signal[0], sizeof(sample)*frame_size); window_frame(in); fftw_execute(p); // calculate sum of prediction errors for(int bin = 0; bin < num_bins; bin++) { /* Magnitude prediction is just the previous magnitude. * Phase prediction is the previous phase plus the difference between * the previous two frames */ phase_prediction = (2.0 * prev_phases[bin]) - prev_phases2[bin]; /* bring it into the range +- pi */ while(phase_prediction > M_PI) phase_prediction -= 2.0 * M_PI; while(phase_prediction < M_PI) phase_prediction += 2.0 * M_PI; /* convert back into the complex domain to calculate stationarities */ prediction[0] = prev_amps[bin] * cos(phase_prediction); prediction[1] = prev_amps[bin] * sin(phase_prediction); /* get stationarity measures in the complex domain */ sum += sqrt(((prediction[0] - out[bin][0])*(prediction[0] - out[bin][0])) + ((prediction[1] - out[bin][1])*(prediction[1] - out[bin][1]))); prev_amps[bin] = sqrt((out[bin][0]*out[bin][0]) + (out[bin][1]*out[bin][1])); prev_phases2[bin] = prev_phases[bin]; prev_phases[bin] = atan2(out[bin][1], out[bin][0]); } return sum; }
sample LPSpectralDifferenceODF::process_frame(int signal_size, sample* signal) { sample sum = 0.0; sample amp = 0.0; sample prediction = 0.0; // do a FFT of the current frame memcpy(in, &signal[0], sizeof(sample)*frame_size); window_frame(in); fftw_execute(p); // calculate the amplitude differences between bins from consecutive frames for(int bin = 0; bin < num_bins; bin++) { amp = sqrt((out[bin][0]*out[bin][0]) + (out[bin][1]*out[bin][1])); /* get LP coefficients */ burg(order, prev_amps[bin], order, order, coefs); /* get the difference between current and predicted values */ linear_prediction(order, prev_amps[bin], order, coefs, 1, &prediction); sum += fabs(amp - prediction); /* move frames back by 1 */ for(int j = 0; j < order-1; j++) { prev_amps[bin][j] = prev_amps[bin][j+1]; } prev_amps[bin][order-1] = amp; } return sum; }
sample SpectralDifferenceODF::process_frame(int signal_size, sample* signal) { sample sum = 0.0; sample amp; int bin; /* do a FFT of the current frame */ memcpy(in, &signal[0], sizeof(sample)*frame_size); window_frame(in); fftw_execute(p); /* calculate the amplitude differences between bins from consecutive frames */ sum = 0.0; for(bin = 0; bin < num_bins; bin++) { amp = sqrt((out[bin][0]*out[bin][0]) + (out[bin][1]*out[bin][1])); sum += fabs(prev_amps[bin] - amp); prev_amps[bin] = amp; } return sum; }
sample LPComplexODF::process_frame(int signal_size, sample* signal) { sample sum = 0.0; sample amp = 0.0; sample prediction = 0.0; sample distance = 0.0; // do a FFT of the current frame memcpy(in, &signal[0], sizeof(sample)*frame_size); window_frame(in); fftw_execute(p); for(int bin = 0; bin < num_bins; bin++) { distance = sqrt((out[bin][0]-prev_frame[bin][0])*(out[bin][0]-prev_frame[bin][0]) + (out[bin][1]-prev_frame[bin][1])*(out[bin][1]-prev_frame[bin][1])); /* get LP coefficients */ burg(order, distances[bin], order, order, coefs); /* get the difference between current and predicted values */ linear_prediction(order, distances[bin], order, coefs, 1, &prediction); sum += fabs(distance - prediction); /* update distances */ for(int j = 0; j < order-1; j++) { distances[bin][j] = distances[bin][j+1]; } distances[bin][order-1] = distance; /* update previous frame */ prev_frame[bin][0] = out[bin][0]; prev_frame[bin][1] = out[bin][1]; } return sum; }
void DatagramConnection::stream_send(const char *buf, const dtn::data::Length &len, bool last) throw (DatagramException) { // build the right flags char flags = 0; // if this is the first segment, then set the FIRST bit if (_send_state == SEND_IDLE) flags |= DatagramService::SEGMENT_FIRST; // if this is the last segment, then set the LAST bit if (last) flags |= DatagramService::SEGMENT_LAST; // set the seqno for this segment unsigned int seqno = _last_ack; IBRCOMMON_LOGGER_DEBUG_TAG(DatagramConnection::TAG, 25) << "frame to send, flags: " << (int)flags << ", seqno: " << seqno << ", len: " << len << IBRCOMMON_LOGGER_ENDL; if (_params.flowcontrol == DatagramService::FLOW_STOPNWAIT) { // measure the time until the ack is received ibrcommon::TimeMeasurement tm; // start time measurement tm.start(); // max. 5 retries for (size_t i = 0; i < _params.retry_limit; ++i) { IBRCOMMON_LOGGER_DEBUG_TAG(DatagramConnection::TAG, 30) << "transmit frame seqno: " << seqno << IBRCOMMON_LOGGER_ENDL; // send the datagram _callback.callback_send(*this, flags, seqno, getIdentifier(), buf, len); // enter the wait state _send_state = SEND_WAIT_ACK; // set timeout to twice the average round-trip-time struct timespec ts; ibrcommon::Conditional::gettimeout(static_cast<size_t>(_avg_rtt * 2) + 1, &ts); try { ibrcommon::MutexLock l(_ack_cond); // wait here for an ACK while (_last_ack != ((seqno + 1) % _params.max_seq_numbers)) { _ack_cond.wait(&ts); } // stop the measurement tm.stop(); // success! _send_state = last ? SEND_IDLE : SEND_NEXT; // adjust the average rtt adjust_rtt(tm.getMilliseconds()); // report result _callback.reportSuccess(i, tm.getMilliseconds()); return; } catch (const ibrcommon::Conditional::ConditionalAbortException &e) { if (e.reason == ibrcommon::Conditional::ConditionalAbortException::COND_TIMEOUT) { IBRCOMMON_LOGGER_DEBUG_TAG(DatagramConnection::TAG, 20) << "ack timeout for seqno " << seqno << IBRCOMMON_LOGGER_ENDL; // fail -> increment the future timeout adjust_rtt(static_cast<double>(_avg_rtt) * 2); // retransmit the frame continue; } else { // aborted break; } } } // maximum number of retransmissions hit _send_state = SEND_ERROR; // report failure _callback.reportFailure(); // transmission failed - abort the stream throw DatagramException("transmission failed - abort the stream"); } else if (_params.flowcontrol == DatagramService::FLOW_SLIDING_WINDOW) { try { // lock the ACK variables and frame window ibrcommon::MutexLock l(_ack_cond); // timeout value struct timespec ts; // set timeout to twice the average round-trip-time ibrcommon::Conditional::gettimeout(static_cast<size_t>(_avg_rtt * 2) + 1, &ts); // wait until window has at least one free slot while (sw_frames_full()) _ack_cond.wait(&ts); // add new frame to the window _sw_frames.push_back(window_frame()); window_frame &new_frame = _sw_frames.back(); new_frame.flags = flags; new_frame.seqno = seqno; new_frame.buf.assign(buf, buf+len); new_frame.retry = 0; // start RTT measurement new_frame.tm.start(); // send the datagram _callback.callback_send(*this, new_frame.flags, new_frame.seqno, getIdentifier(), &new_frame.buf[0], new_frame.buf.size()); // increment next sequence number _last_ack = (seqno + 1) % _params.max_seq_numbers; // enter the wait state _send_state = SEND_WAIT_ACK; // set timeout to twice the average round-trip-time ibrcommon::Conditional::gettimeout(static_cast<size_t>(_avg_rtt * 2) + 1, &ts); // wait until one more slot is available // or no more frames are to ACK (if this was the last frame) while ((last && !_sw_frames.empty()) || (!last && sw_frames_full())) { _ack_cond.wait(&ts); } } catch (const ibrcommon::Conditional::ConditionalAbortException &e) { if (e.reason == ibrcommon::Conditional::ConditionalAbortException::COND_TIMEOUT) { // timeout - retransmit the whole window sw_timeout(last); } else { // maximum number of retransmissions hit _send_state = SEND_ERROR; // report failure _callback.reportFailure(); // transmission failed - abort the stream throw DatagramException("transmission failed - abort the stream"); } } // if this is the last segment switch directly to IDLE _send_state = last ? SEND_IDLE : SEND_NEXT; } else { IBRCOMMON_LOGGER_DEBUG_TAG(DatagramConnection::TAG, 30) << "transmit frame seqno: " << seqno << IBRCOMMON_LOGGER_ENDL; // send the datagram _callback.callback_send(*this, flags, seqno, getIdentifier(), buf, len); // if this is the last segment switch directly to IDLE _send_state = last ? SEND_IDLE : SEND_NEXT; // increment next sequence number ibrcommon::MutexLock l(_ack_cond); _last_ack = (seqno + 1) % _params.max_seq_numbers; } }