Ejemplo n.º 1
0
int soundfile_insert_silence(long linsert_pos, long lsample_count,
                             int status_info)
{
    sf_count_t insert_pos = linsert_pos;
    sf_count_t sample_count = lsample_count;
    sf_count_t end_pos = sf_seek(sndfile, 0, SEEK_END|SFM_READ);
    int rc = 0;

    if (insert_pos < 0 || insert_pos > end_pos)
        insert_pos = end_pos;

    if (soundfile_shift_samples_right(insert_pos, sample_count, status_info) < 0) {
        rc = -1;
    }
    else if (write_silence(insert_pos, sample_count) < 0) {
        rc = -1;
    }

    return rc;
}
Ejemplo n.º 2
0
/* append 'sample_count' samples and shift all samples from 'first_pos'
 * to end of file (this creates 'sample_count' samples at 'first_pos')
 */
int soundfile_shift_samples_right(long lfirst_pos, long lsample_count,
                                  int status_info)
{
    sf_count_t first_pos = lfirst_pos;
    sf_count_t sample_count = lsample_count;
    sf_count_t end_pos = sf_seek(sndfile, 0, SEEK_END|SFM_READ);

    if (sample_count <= 0) {
        puts("soundfile_shift_samples_right: no samples to move");
        return 0;
    }

/*     printf("soundfile_shift_samples_right: " */
/*            "first_pos=%lld, shift=%lld, samples in file=%lld\n", */
/*            first_pos, sample_count, end_pos); */

    if (first_pos < end_pos) {
        sf_count_t processed = 0;
        sf_count_t read_pos, write_pos;
        int channels = sfinfo.channels;
#define TMPBUFSIZE     (4*SBW*1000)
        int buffer[TMPBUFSIZE];
        sf_count_t buffer_size = TMPBUFSIZE/channels;

        /* go to end position and append enough space for the new data */
        if (write_silence(end_pos, sample_count) < 0) {
            return -1;
        }

        /* loop reading-writing from end */
        write_pos = end_pos + sample_count;
        read_pos  = end_pos;

        while (read_pos > first_pos) {
            if (buffer_size > read_pos - first_pos)
                buffer_size = read_pos - first_pos;

            write_pos -= buffer_size;
            read_pos  -= buffer_size;

/*             printf("soundfile_shift_samples_right: " */
/*                    "read_pos=%lld, write_pos=%lld, diff=%lld, buffer_size=%lld\n", */
/*                    read_pos, write_pos, write_pos-read_pos, buffer_size); */

            /* start position for reading */
            if (sf_seek(sndfile, read_pos, SEEK_SET|SFM_READ) < 0) {
                perr("soundfile_shift_samples_right: sf_seek read pointer");
                warning("Libsndfile reports read pointer seek error in audio file");
                return -1;
            }
            if (sf_readf_int(sndfile, buffer, buffer_size) != buffer_size) {
                perr("soundfile_shift_samples_right: sf_readf_int");
                warning("Libsndfile reports read error in audio file");
                return -1;
            }

            /* start position for writing */
            if (sf_seek(sndfile, write_pos, SEEK_SET|SFM_WRITE) < 0) {
                perr("soundfile_shift_samples_right: sf_seek write pointer");
                warning("Libsndfile reports write pointer seek error in audio file");
                return -1;
            }
            if (sf_writef_int(sndfile, buffer, buffer_size) != buffer_size) {
                perr("soundfile_shift_samples_right: sf_writef_int");
                warning("Libsndfile reports write error in audio file");
                return -1;
            }

            processed += buffer_size;
            if (status_info)
                update_progress_bar((gfloat)processed/(end_pos-first_pos),
                                  PROGRESS_UPDATE_INTERVAL, FALSE);

/*             printf("soundfile_shift_samples_right: processed=%lld (%f.2)\n", */
/*                    processed, (gfloat)processed/(end_pos-first_pos)); */
        }
    }

/*     printf("soundfile_shift_samples_right: samples in file=%lld\n", */
/*            sf_seek(sndfile, 0, SEEK_END|SFM_READ)); */

    adjust_all_marker_positions(first_pos, sample_count);
    return 0;
}
Ejemplo n.º 3
0
/* recv_packet processes a received audio packet.  The packet has
   sequence number seqno, and consists of len bytes of data.  In this
   case, it's just PCM, encoded in 16-bit linear format.  The
   "strategy" parameter determines which of several possible loss
   concealment techniques to apply */
void recv_packet(int seqno, int len, char *data, FILE *ofile, int strategy) {
  static int prev_seqno = -1;
  static int16_t* prev_packet_samples = 0;
  int16_t *samples = (int16_t*)data; /* we receive a bunch of bytes
					from the (simulated) net, but
					we know they're really 16 bit
					sample values.  In real life
					we'd convert them from network
					byte order to host byte order,
					but no need to do that here */
  int num_samples = len/2;  /* two bytes to a 16 bit integer */
  printf("recv_packet: seqno=%d\n", seqno);

  if (prev_seqno != -1 && (prev_seqno+1 != seqno)) {
    /* there was missing data - we need to replace it */
    int missing_seqno;

    switch(strategy) {
    case SILENCE: 
      {
	/* create as many packet containing silence as we need to fill the gap */
	missing_seqno = prev_seqno + 1;
	while (missing_seqno < seqno) {
	  write_silence(ofile, num_samples);
	  missing_seqno++;
	}
	break;
      }
    case REPEAT_PREV: 
      {
	/* repeat the previous packet once to fill the gap.  If the
	   gap is longer than one packet, fill the remainder with
	   silence */
	fwrite(prev_packet_samples, 2, num_samples, ofile);
	missing_seqno = prev_seqno + 2;
	while (missing_seqno < seqno) {
	  write_silence(ofile, num_samples);
	  missing_seqno++;
	}
	break;
      }
    case REPEAT_NEXT: 
      {
	/* play the next packet (twice) to fill the gap.  If the gap
	   is longer than one packet, first insert silence, then
	   insert the next packet */
	missing_seqno = prev_seqno + 1;
	while (missing_seqno < seqno) {
	  if (missing_seqno == seqno-1) {
	    /* only repeat back once */
	    /* write the current packet instead of the missing one */
	    fwrite(data, 2, num_samples, ofile);
	  } else {
	    write_silence(ofile, num_samples);
	  }
	  missing_seqno++;
	}
	break;
      }
    case REPEAT_BOTH: 
      {
	/* we'll fill the gap with data from both before and after the
	   gap.  If the gap is one packet long, repeat the last half
	   of the previous packet and the first half of the next
	   packet.  If the gap is two packets long, repeat the whole
	   previous packet, then the whole next packet.  If the gap is
	   three of more packets long, fill the remainder with
	   silence. */
	missing_seqno = prev_seqno + 1;
	if (missing_seqno == seqno-1) {
	  /* the gap is only one packet long */
	  /* fill with last half of prev packet, first half of current packet */

	  /* uncomment the next line to enable smoothing*/
#define SMOOTH
#ifdef SMOOTH
	  
          int16_t prev = ((prev_packet_samples[num_samples-1] * 0.66) + (samples[0] * 0.33));
          int16_t prev2 = ((prev_packet_samples[num_samples-2] * 0.5) + (prev * 0.5));

          int16_t next = ((prev_packet_samples[num_samples-1] * 0.33) + (samples[0] * 0.66));      
          int16_t next2 = ((next * 0.5) + (samples[1] * 0.5));

	  fwrite(prev_packet_samples+num_samples/2, 2, (num_samples/2) - 2, ofile);
	  fwrite(&prev2, 2, 1, ofile);
	  fwrite(&prev, 2, 1, ofile);
	  fwrite(&next, 2, 1, ofile);
	  fwrite(&next2, 2, 1, ofile);
	  fwrite(samples + 2, 2, (num_samples/2) - 2, ofile);
	   
	  
#else
	  fwrite(prev_packet_samples+num_samples/2, 2, num_samples/2, ofile);
	  fwrite(samples, 2, num_samples/2, ofile);
#endif
	} else {
	  /* the gap is two or more packets long */
	  /* first write the prev packet a second time */
	  fwrite(prev_packet_samples, 2, num_samples, ofile);
	  missing_seqno++;
	  while (missing_seqno < seqno) {
	    if (missing_seqno == seqno-1) {
	      /* write the current packet instead of the missing one */
	      fwrite(samples, 2, num_samples, ofile);
	    } else {
	      write_silence(ofile, num_samples);
	    }
	    missing_seqno++;
	  }
	}
	break;
      }
    case INTERPOLATE:
      {
	/* We're going to interpolate a whole new packet (or several packets) in the frequency domain. */
	if (seqno < (prev_seqno + 5)) {
    	        int *prev_coeff = dct(prev_packet_samples, num_samples);
		int *next_coeff = dct(samples, num_samples);
	
		missing_seqno = prev_seqno + 1;
	
		while (missing_seqno < seqno) {
			double next_weight = (double)(missing_seqno - prev_seqno)/(seqno - prev_seqno);
			double prev_weight = (double)(seqno - missing_seqno)/(seqno - prev_seqno);
			
			int new_coeff[num_samples];
			int i;
			for (i = 0; i < num_samples; i++) {
				new_coeff[i] = (prev_weight * prev_coeff[i]) + (next_weight * next_coeff[i]);
					
			}
			fwrite(idct(new_coeff, num_samples), 2, num_samples, ofile);
			missing_seqno++;
		}
	} else {
		missing_seqno = prev_seqno + 1;
		while (missing_seqno < seqno) {
	  		write_silence(ofile, num_samples);
	  		missing_seqno++;
		}
	}
	break;
      }
    }
  }
  /* finally, don't forget to write out the packet that arrived after the gap */
  fwrite(samples, 2, num_samples, ofile);
  
  /* hold onto the last received packet - we may need it */
  if (prev_packet_samples != 0)
    free(prev_packet_samples);
  prev_packet_samples = samples;
  prev_seqno = seqno;
};