user1058210
user1058210

Reputation: 1689

C/C++ - Understanding Audio interpolation code

The code below is intended to implement two strategies to interpolate across missing packets - the two strategies are 1) fill the gap with silence, or 2) repeat the previous packet and if longer than one packet fill the rest with silence. The code has broad comments but I can't seem to get my head around what the different variables are supposed to mean. Would someone mind giving me a helping hand understanding this code? Appreciate any guidance!

#include "interpolate.h"
#include "assert.h"

/* write a packet's worth of silence */
void write_silence(FILE *ofile, int num_samples) {
  short missing_pkt[num_samples];
  int i;
  for (i=0; i < num_samples; i++) {
    missing_pkt[i]=0;
  }
  fwrite(missing_pkt, 1, num_samples*2, ofile);
}

/* simulate the reception of a packet, and apply a loss repair strategy */
void recv_packet(int seqno, int len, char *data, FILE *ofile, int strategy) {
  static int prev_seqno = -1;
  static short* prev_samples = 0;

  /* interpret the data as signed 16 bit integers */
  short *samples = (short*)data; 
  int num_samples = len/2;

  printf("recv_packet: seqno=%d\n", seqno);

  if (prev_seqno != -1 && (prev_seqno+1 != seqno)) {
    int i, missing_seqno;
    /* there was missing data */

    printf("s=%d\n", strategy);
    switch(strategy) {
    case SILENCE: 
      {
    /* create a packet containing silence */
    missing_seqno = prev_seqno + 1;
    while (missing_seqno < seqno) {
      write_silence(ofile, num_samples);
      missing_seqno++;
    }
    break;
      }
    case REPEAT_PREV: 
      {
    /* repeat the previous packet */
    fwrite(prev_samples, 2, num_samples, ofile);
    missing_seqno = prev_seqno + 2;
    while (missing_seqno < seqno) {
      /* repeating the same packet more than once sounds bad */
      write_silence(ofile, num_samples);
      missing_seqno++;
    }
    break;
      }

    default:
      abort();
    }
  }

  fwrite(samples, 1, num_samples*2, ofile);

  /* hold onto the last received packet - we may need it */
  if (prev_samples != 0)
    free(prev_samples);
  prev_samples = samples;
  prev_seqno = seqno;
};

Upvotes: 1

Views: 750

Answers (1)

UmNyobe
UmNyobe

Reputation: 22890

Variables convention :

  • seqno : sequence number
  • samples : audio data as samples
  • prev_ : previous
  • ofile : output file

How do you know what the code is supposed to do without understanding it? The idea is that packets have incremental sequence numbers, from 0 to infinity. -1 is the initial state, when no packets have even been received. When you receive a packet and

  if (prev_seqno != -1 //it is not the first packet 
      && 
     (prev_seqno+1 != seqno) //the packet is not the one we expected  
      ){ 
   //there are (seqno - prev_seqno - 1) packet missing.
   //do something about it.

when you enter this condition then you have a gap. Depending on the strategy you fill the output file ofile with silence or copy of the last samples received. In audio silence = 0.

For example, if the last packet was 0 and you received packet 4, it means packet 1, 2 and 3 are missing. In this case depending on the strategy you will consider 1, 2, 3 as silence packets or as 0 being repeated.

Upvotes: 1

Related Questions