% FUNCTION P2 = WAV_SEGMENT( P )
%
% To extract a subset of a recording (list of segments).
% Optionally the complementary subset can also be extracted.
%
% P.INDEX_SEC (default 0): Optionally a fake "index" sound can be appended to the beginning
% of each segment -> this way you directly see the segment index
% in the waveform. P.INDEX_SEC is the duration of this segment.
% 
% Output: one (optionally two) wavefiles.
%
% Typical usage: output one wavefile with speech,
% one with non-speech.
%
% Parameters are passed as fields of p.
%   p.in_name:  name of the input wavfile
%   p.seg:      2 - by - n_seg matrix. First row is start, second row
%               is end (in seconds).
%
% To see the list of all parameters:
%   dbtype wav_segment   
%
% lathoud@idiap.ch

function p2 = wav_segment( p )

if nargin < 1
  error( 'wav_segment needs one parameter' );
end

required_param = { 'in_name', 'seg' };
check_param( required_param, fieldnames( p ) );

p_default.in_dir = '';
p_default.out_dir = '';
p_default.out_name_subset = [];   % [] means default name
p_default.out_name_complementary = [];   % means default name

p_default.generate_subset = 1;
p_default.generate_complementary = 0;

p_default.index_sec = 0;     % Duration of the fake index sound in the produced WAV file

p_default.verbose = 1;

p = fill_default( p, p_default );

if p.generate_subset & isempty( p.out_name_subset )
  p.out_name_subset = [ strtok( p.in_name, '.' ) '_subset.wav' ];
end

if p.generate_complementary & isempty( p.out_name_complementary )
  p.out_name_complementary = [ strtok( p.in_name, '.' ) '_complementary.wav' ];
end

v = size( p.seg );
if length( v ) ~= 2
  error( 'wav_segment: wrong size for p.seg! Must be a n_seg - by - 2 matrix' );
end
if v(1) ~= 2
  error( 'wav_segment: wrong size for p.seg! Must be a n_seg - by - 2 matrix' );
end
if v(2) < 1
  error( 'wav_segment: nothing to do! Check p.seg' );
end
if ~ ((p.generate_subset>0) + (p.generate_complementary>0))
  error( 'wav_segment: nothing to do! Check p.generate_subset and p.generate_complementary' );
end

if p.verbose
  
  disp( ' ' );
  disp( 'wav_segment parameters: ' );
  disp( p );
  disp( 'wav_segment: output in:' );
  disp( [ '"' fullfile( p.out_dir, p.out_name_subset ) '"' ] );
  if p.generate_complementary
    disp( [ '"' fullfile( p.out_dir, p.out_name_complementary ) '"' ] );
  end
  
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Try to open files

% Input

in_filename = fullfile( p.in_dir, p.in_name );
in_fid = fopen( in_filename, 'r' );
if in_fid < 0
  error( sprintf( 'wav_segment could not read-open %s', in_filename ) );
end
fclose( in_fid );

% Output

if p.generate_subset
  out_filename_subset = fullfile( p.out_dir, p.out_name_subset );
  out_fid_subset = fopen( out_filename_subset, 'w' );
  if out_fid_subset < 0
    error( sprintf( 'wav_segment could not write-open %s', out_filename_subset ) );
  end
  fclose( out_fid_subset );
end

if p.generate_complementary
  out_filename_complementary = fullfile( p.out_dir, p.out_name_complementary );
  out_fid_complementary = fopen( out_filename_complementary, 'w' );
  if out_fid_complementary < 0
    error( sprintf( 'wav_segment could not write-open %s', out_filename_complementary ) );
  end
  fclose( out_fid_complementary );
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Do it!

seg = p.seg.';

[y, in_fs, in_nbits] = wavread( in_filename, [ 1 1 ] );
in_size = wavread( in_filename, 'size' );

index_samples = round( p.index_sec * in_fs );

if p.generate_subset
  n_seg = size( seg, 1 );
  out_y = [];
  for a = 1:n_seg
    s = 1 + round( seg( a, 1 ) * in_fs );
    s = max( min( s, in_size(1) ), 1 );
    e = 1 + round( seg( a, 2 ) * in_fs );
    e = max( min( e, in_size(1) ), 1 );
    
    index_y = [];
    if index_samples > 0
      index_y = repmat( mod( a, 32767 ), index_samples, 1 );
      index_y( [1 end] ) = -15000;
      index_y = index_y / 32768;
    end
    
    out_y = [ out_y ; index_y; wavread( in_filename, [ s e ] ) ];
  end
  wavwrite( out_y, in_fs, in_nbits, out_filename_subset );
end

if p.generate_complementary
  compl_seg = [ seg(1:end-1, 2) seg(2:end,1) ];
  compl_seg = [ 0 seg( 1, 1 ); 
		compl_seg; 
		seg( end, end ) in_size(1) / in_fs ];
  n_seg = size( compl_seg, 1 );
  out_y = [];
  for a = 1:n_seg
    s = 1 + round( compl_seg( a, 1 ) * in_fs );
    s = max( min( s, in_size(1) ), 1 );
    e = 1 + round( compl_seg( a, 2 ) * in_fs );
    e = max( min( e, in_size(1) ), 1 );

    index_y = [];
    if index_samples > 0
      index_y = repmat( mod( a, 32767 ), index_samples, 1 );
      index_y( [1 end] ) = -15000;
      index_y = index_y / 32768;
    end
    
    out_y = [ out_y ; index_y; wavread( in_filename, [ s e ] ) ];
  end
  
  wavwrite( out_y, in_fs, in_nbits, out_filename_complementary );
end

% Return augmented parameters

p2 = p;
