Exemplo n.º 1
0
SNDFILE*
open_input_file( char* filename )
{
    SNDFILE* file = NULL;


    // Do they want STDIN ?
    if (strncmp( filename, "-", 1 )==0) {

        // We only support raw audio on STDIN
        sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_16;

        // Open the file descriptor
        file = sf_open_fd(STDIN_FILENO, SFM_READ, &sfinfo, TRUE);
        
    } else {
    
		// Open the input file by filename
		file = sf_open(filename, SFM_READ, &sfinfo);
		
	}
    
    // Check for errors
    if (file == NULL) {
        fprintf(stderr, "Failed to open input file (%s):\n", filename);
        fprintf(stderr, "  %s\n", sf_strerror(NULL));
        exit(ERR_OPENING_INPUT);
    }
        
    return file;
}
Exemplo n.º 2
0
static void
write_file_at_end (int fd, int filetype, int channels, int file_num)
{	SNDFILE *sndfile ;
	SF_INFO sfinfo ;

	int	frames, k ;

	lseek (fd, 0, SEEK_END) ;

	for (k = 0 ; k < DATA_LENGTH ; k++)
		data [k] = k ;

	frames = DATA_LENGTH / channels ;

	sfinfo.format = filetype ;
	sfinfo.channels = channels ;
	sfinfo.samplerate = 44100 ;

	if ((sndfile = sf_open_fd (fd, SFM_WRITE, &sfinfo, SF_FALSE)) == NULL)
	{	printf ("\n\nLine %d: sf_open_fd failed\n", __LINE__) ;
		printf ("Embedded file number : %d\n", file_num) ;
		puts (sf_strerror (sndfile)) ;
		dump_log_buffer (sndfile) ;
		exit (1) ;
		} ;

	if (sf_writef_short (sndfile, data, frames) != frames)
	{	printf ("\n\nLine %d: short write\n", __LINE__) ;
		printf ("Embedded file number : %d\n", file_num) ;
		exit (1) ;
		} ;

	sf_close (sndfile) ;
} /* write_file_at_end */
Exemplo n.º 3
0
static void open_io(struct holder *holder, const char *filename)
{
	int err;

	if (!strcmp(filename, "-"))
		holder->infile = sf_open_fd(STDIN_FILENO, SFM_READ,
				&holder->ininfo, 1);
	else
		holder->infile = sf_open(filename, SFM_READ, &holder->ininfo);

	if (holder->infile == NULL)
		errx(1, "open in: %s", sf_strerror(NULL));

	err = snd_pcm_open(&holder->alsa_handle, "default",
			SND_PCM_STREAM_PLAYBACK, 0);
	if (err < 0)
		errx(1, "alsa open: %s", snd_strerror(err));

	err = snd_pcm_set_params(holder->alsa_handle, SND_PCM_FORMAT_FLOAT,
			SND_PCM_ACCESS_RW_INTERLEAVED, holder->ininfo.channels,
			holder->ininfo.samplerate, 1, 500000);
	if (err < 0)
		errx(1, "alsa set_params: %s", snd_strerror(err));

	initscr();
	start_color();
	init_pair(1, COLOR_BLUE, COLOR_BLACK);
	init_pair(2, COLOR_WHITE, COLOR_BLACK);
	getmaxyx(stdscr, holder->height, holder->width);
}
Exemplo n.º 4
0
soundfile_t *
soundfile_open_read(const char *path) {
	dp(30, "path=%s \n", path);
	soundfile_t *s = salloc(sizeof *s);
	s->m = sft_read;
	if 	(g_regex_match_simple ("\\.wv$", path, 0, 0)) {
		char error[80] = {0};
	    int flags = 0;
	    int norm_offset = 0;
		s->t = sft_wavpack;
	    s->p = WavpackOpenFileInput(path, error, flags, norm_offset);
		if (!s->p)
			die("can not open input file '%s'", path);
		s->bits_per_sample = WavpackGetBitsPerSample(s->p);
		s->channels = WavpackGetNumChannels(s->p);
		s->samplerate = WavpackGetSampleRate(s->p);
		s->frames = WavpackGetNumSamples(s->p);
	} else {
		SF_INFO	 	infile_info = {0};
		if (strcmp(path, "-"))
			s->p = sf_open(path, SFM_READ, &infile_info);
		else
			s->p = sf_open_fd(0, SFM_READ, &infile_info, 0);
		if (!s->p)
			die("can not open input file '%s'", path);
		s->t = sft_libsndfile;
		s->channels = infile_info.channels;
		s->samplerate = infile_info.samplerate;
		s->frames = infile_info.frames;
	}
	return s;
}
Exemplo n.º 5
0
int
sndfile_open(struct audio_file *fd, const char *ext)
{
	SNDFILE *hnd;
	SF_INFO info;
	int fno;

	if (fd->stream) {
		/* Not yet */
		return (-1);
	}

	/* Rewind the file to the beginning */
	fno = fileno(fd->fp);
	lseek(fno, 0, SEEK_SET);

	if ((hnd = sf_open_fd(fno, SFM_READ, &info, 0)) == NULL)
		return (-1);
	fd->drv_data = (void *)hnd;

	fd->srate = info.samplerate;
	fd->channels = info.channels;
	fd->time_len = info.frames / fd->srate;

	/* Metadata - libsndfile only has artist + title */
	fd->artist = g_strdup(sf_get_string(hnd, SF_STR_ARTIST));
	fd->title = g_strdup(sf_get_string(hnd, SF_STR_TITLE));
	fd->album = g_strdup(sf_get_string(hnd, SF_STR_ALBUM));

	return (0);
}
Exemplo n.º 6
0
	void Sound::createFromFile(const std::string& szFileName) {
#ifndef NO_SOUND
		if(enabled) {
			bool err = false;
			
			//Open stream
			SNDFILE* stream = nullptr;
			SF_INFO info;
			//memset(&info, 0, sizeof(_info));

			std::string path = util::getPath(szFileName);
			FILE* fp = util::ufopen(path, "rb");
			if(!fp) {
				goto error;
			}
			stream = sf_open_fd(fileno(fp), SFM_READ, &info, SF_FALSE);

			if(!stream) {
				goto error;
			}

			//Get size of buffer and allocate memory
			c_samples = info.frames;
			channels = info.channels;
			sample_rate = info.samplerate;
			samples = new float[c_samples * channels];

			if(sf_readf_float(stream, samples, c_samples) != c_samples) {
				goto error;
			}
			goto end;

	error:
			if(samples) {
				delete [] samples;
				samples = nullptr;
			}
			c_samples = 0;
			channels = 0;
			err = true;

	end:
			if(stream) {
				sf_close(stream);
			}
			if(fp) {
				fclose(fp);
			}
			
			if(err) {
				die("Unable to load audio file \"" + path + "\".");
			}
		}
#endif
	}
Exemplo n.º 7
0
static void
error_close_test (void)
{	static short buffer [SHORT_BUFFER] ;
	const char	*filename = "error_close.wav" ;
	SNDFILE		*sndfile ;
	SF_INFO		sfinfo ;
	FILE		*file ;

	print_test_name (__func__, filename) ;

	/* Open a FILE* from which we will extract a file descriptor. */
	if ((file = fopen (filename, "w")) == NULL)
	{	printf ("\n\nLine %d : fopen returned NULL.\n", __LINE__) ;
		exit (1) ;
	} ;

	/* Set parameters for writing the file. */
	memset (&sfinfo, 0, sizeof (sfinfo)) ;
	sfinfo.channels = 1 ;
	sfinfo.samplerate = 44100 ;
	sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16 ;

	sndfile = sf_open_fd (fileno (file), SFM_WRITE, &sfinfo, SF_TRUE) ;
	if (sndfile == NULL)
	{	printf ("\n\nLine %d : sf_open_fd failed : %s\n", __LINE__, sf_strerror (NULL)) ;
		exit (1) ;
	} ;

	test_write_short_or_die (sndfile, 0, buffer, ARRAY_LEN (buffer), __LINE__) ;

	/* Now close the fd associated with file before calling sf_close. */
	fclose (file) ;

	if (sf_close (sndfile) == 0)
	{
#if OS_IS_WIN32
		OSVERSIONINFOEX osvi ;

		memset (&osvi, 0, sizeof (OSVERSIONINFOEX)) ;
		osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX) ;

		if (GetVersionEx ((OSVERSIONINFO *) &osvi))
		{	printf ("\n\nLine %d : sf_close should not have returned zero.\n", __LINE__) ;
			printf ("\nHowever, this is a known bug in version %d.%d of windows so we'll ignore it.\n\n",
							(int) osvi.dwMajorVersion, (int) osvi.dwMinorVersion) ;
		} ;
#else
		printf ("\n\nLine %d : sf_close should not have returned zero.\n", __LINE__) ;
		exit (1) ;
#endif
	} ;

	unlink (filename) ;
	puts ("ok") ;
} /* error_close_test */
Exemplo n.º 8
0
SNDFILE *open_output(const char *file, SF_INFO *info)
{
    SNDFILE *fp;
    if (!file || !strcmp(file, "-")) {
	if (!(fp = sf_open_fd(1, SFM_WRITE, info, 0)))
	    fputs("ERROR: sf_open_fd()\n", stderr);
    } else {
	if (!(fp = sf_openx(file, SFM_WRITE, info)))
	    fprintf(stderr, "ERROR: sf_open()\n");
    }
    return fp;
}
Exemplo n.º 9
0
static int startwrite(sox_format_t * ft)
{
  priv_t * sf = (priv_t *)ft->priv;
  start(ft);
  /* If output format is invalid, try to find a sensible default */
  if (!sf_format_check(sf->sf_info)) {
    SF_FORMAT_INFO format_info;
    int i, count;

    sf_command(sf->sf_file, SFC_GET_SIMPLE_FORMAT_COUNT, &count, (int) sizeof(int));
    for (i = 0; i < count; i++) {
      format_info.format = i;
      sf_command(sf->sf_file, SFC_GET_SIMPLE_FORMAT, &format_info, (int) sizeof(format_info));
      if ((format_info.format & SF_FORMAT_TYPEMASK) == (sf->sf_info->format & SF_FORMAT_TYPEMASK)) {
        sf->sf_info->format = format_info.format;
        /* FIXME: Print out exactly what we chose, needs sndfile ->
           sox encoding conversion functions */
        break;
      }
    }

    if (!sf_format_check(sf->sf_info)) {
      lsx_fail("cannot find a usable output encoding");
      return SOX_EOF;
    }
    if ((sf->sf_info->format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
      lsx_warn("cannot use desired output encoding, choosing default");
  }

  sf->sf_file = sf_open_fd(fileno(ft->fp), SFM_WRITE, sf->sf_info, 1);
  ft->fp = NULL; /* Transfer ownership of fp to LSF */
  drain_log_buffer(ft);

  if (sf->sf_file == NULL) {
    memset(ft->sox_errstr, 0, sizeof(ft->sox_errstr));
    strncpy(ft->sox_errstr, sf_strerror(sf->sf_file), sizeof(ft->sox_errstr)-1);
    free(sf->sf_file);
    return SOX_EOF;
  }

#ifdef HAVE_SFC_SET_SCALE_INT_FLOAT_WRITE
  if ((sf->sf_info->format & SF_FORMAT_SUBMASK) == SF_FORMAT_FLOAT)
    sf_command(sf->sf_file, SFC_SET_SCALE_INT_FLOAT_WRITE, NULL, SF_TRUE);
#endif
           
  return SOX_SUCCESS;
}
Exemplo n.º 10
0
/*
 * Open file in sndfile.
 */
static int startread(sox_format_t * ft)
{
  priv_t * sf = (priv_t *)ft->priv;
  unsigned bits_per_sample;
  sox_encoding_t encoding;
  sox_rate_t rate;

  start(ft);

  sf->sf_file = sf_open_fd(fileno(ft->fp), SFM_READ, sf->sf_info, 1);
  ft->fp = NULL; /* Transfer ownership of fp to LSF */
  drain_log_buffer(ft);

  if (sf->sf_file == NULL) {
    memset(ft->sox_errstr, 0, sizeof(ft->sox_errstr));
    strncpy(ft->sox_errstr, sf_strerror(sf->sf_file), sizeof(ft->sox_errstr)-1);
    free(sf->sf_file);
    return SOX_EOF;
  }

  if (!(encoding = sox_enc(sf->sf_info->format, &bits_per_sample))) {
    lsx_fail_errno(ft, SOX_EFMT, "unsupported sndfile encoding %#x", sf->sf_info->format);
    return SOX_EOF;
  }

  /* Don't believe LSF's rate for raw files */
  if ((sf->sf_info->format & SF_FORMAT_TYPEMASK) == SF_FORMAT_RAW && !ft->signal.rate) {
    lsx_warn("`%s': sample rate not specified; trying 8kHz", ft->filename);
    rate = 8000;
  }
  else rate = sf->sf_info->samplerate;

#ifdef HAVE_SFC_SET_SCALE_FLOAT_INT_READ
  if ((sf->sf_info->format & SF_FORMAT_SUBMASK) == SF_FORMAT_FLOAT) {
    sf_command(sf->sf_file, SFC_SET_SCALE_FLOAT_INT_READ, NULL, SF_TRUE);
    sf_command(sf->sf_file, SFC_SET_CLIPPING, NULL, SF_TRUE);
  }
#endif

#if 0 /* FIXME */
    sox_append_comments(&ft->oob.comments, buf);
#endif

  return check_read_params(ft, (unsigned)sf->sf_info->channels, rate,
      encoding, bits_per_sample, (off_t)(sf->sf_info->frames * sf->sf_info->channels));
}
Exemplo n.º 11
0
soundfile_t *
soundfile_open_write(const char *path, int n_channels, double sampling_rate) {
	dp(30, "path=%s n_channels=%d sampling_rate=%g\n", path, n_channels, sampling_rate);
	soundfile_t *s = salloc(sizeof *s);
	s->m = sft_write;
	s->channels = n_channels;
	s->samplerate = sampling_rate;
	if 	(g_regex_match_simple ("\\.wv$", path, 0, 0)) {
		s->t = sft_wavpack;
		s->file = fopen(path, "w+b");
		if (!s->file)
			die("can not open output file '%s'", path);
		WavpackContext *wpc = s->p = WavpackOpenFileOutput(write_block, s, NULL);
		if (!s->p)
			die("can not open input file '%s'", path);
  		WavpackConfig config = {0};
		config.bytes_per_sample = 2;
		s->bits_per_sample = config.bits_per_sample = 16;
		config.channel_mask = n_channels == 1 ? 4 : 3; // Microsoft standard: 4 == mono, 3 == stereo
		config.num_channels = n_channels;
		config.sample_rate = sampling_rate;
		if (!WavpackSetConfiguration(wpc, &config, -1))
        	die("WavpackSetConfiguration failed: %s\n", WavpackGetErrorMessage(wpc));
		if (!WavpackPackInit(wpc))
        	die("WavpackPackInit failed: %s\n", WavpackGetErrorMessage(wpc));
			
	} else {
		SF_INFO	 	outfile_info = {0};
		outfile_info.samplerate = sampling_rate;
		outfile_info.channels = n_channels;
		outfile_info.format = SF_FORMAT_PCM_16;
		
		if (g_regex_match_simple ("\\.flac$", path, 0, 0))
			outfile_info.format |= SF_FORMAT_FLAC;
		else
			outfile_info.format |= SF_FORMAT_WAV;
		if (strcmp(path, "-"))
			s->p = sf_open(path, SFM_WRITE, &outfile_info);
		else
			s->p = sf_open_fd(1, SFM_WRITE, &outfile_info, 0);  // write to stdout if name is "-"
		if (!s->p)
			die("can not open output file '%s'", path);
		s->t = sft_libsndfile;
	}
	return s;
}
Exemplo n.º 12
0
int cf_sndfile_read(CODECFILTER_USERDATA_T   inst, char * buf, int len) {
 struct codecfilter_sndfile_inst * obj = (struct codecfilter_sndfile_inst *) inst;
 struct roar_stream * s = ROAR_STREAM(obj->stream);
 int ret;

 if ( obj->opened ) {
  len /= obj->bytes;

  if ( obj->bytes == 2 ) {
   if ( (ret = sf_read_short(obj->state, (short*)buf, len)) == -1 )
    return -1;
  } else if ( obj->bytes == 4 ) {
   if ( (ret = sf_read_int(obj->state, (int*)buf, len)) == -1 )
    return -1;
  } else {
   errno = ENOSYS;
   return -1;
  }

  return ret * obj->bytes;
 } else {
  if ( (obj->state = sf_open_fd(s->fh, SFM_READ, &(obj->info), 0)) == NULL ) {
   ROAR_ERR("cf_sndfile_read(*): can not sf_open_fd(*)!");
   return -1;
  }
  ROAR_WARN("cf_sndfile_read(*): obj->info={.format=0x%.8x, .samplerate=%i, .channels=%i}", obj->info.format, obj->info.samplerate, obj->info.channels);

  s->info.codec    = ROAR_CODEC_DEFAULT;
  s->info.rate     = obj->info.samplerate;
  s->info.channels = obj->info.channels;

  obj->bytes       = 2;
  if ( (obj->info.format & SF_FORMAT_SUBMASK) == SF_FORMAT_PCM_24 ||
       (obj->info.format & SF_FORMAT_SUBMASK) == SF_FORMAT_PCM_32   ) {
   obj->bytes      = 4;
  }

  s->info.bits     = obj->bytes * 8;

  obj->opened      = 1;
  errno = EAGAIN;
 }

 return -1;
}
Exemplo n.º 13
0
static void *sndfile_open (const char *file)
{
	int fd;
	struct sndfile_data *data;

	data = (struct sndfile_data *)xmalloc (sizeof(struct sndfile_data));

	decoder_error_init (&data->error);
	memset (&data->snd_info, 0, sizeof(data->snd_info));
	data->timing_broken = false;

	fd = open (file, O_RDONLY);
	if (fd == -1) {
		char *err = xstrerror (errno);
		decoder_error (&data->error, ERROR_FATAL, 0,
		               "Can't open file: %s", err);
		free (err);
		return data;
	}

	/* sf_open_fd() close()s 'fd' on error and in sf_close(). */
	data->sndfile = sf_open_fd (fd, SFM_READ, &data->snd_info, SF_TRUE);
	if (!data->sndfile) {
		/* FIXME: sf_strerror is not thread safe with NULL argument */
		decoder_error (&data->error, ERROR_FATAL, 0,
				"Can't open file: %s", sf_strerror(NULL));
		return data;
	}

	/* If the timing is broken, sndfile only decodes up to the broken value. */
	data->timing_broken = is_timing_broken (fd, data);
	if (data->timing_broken) {
		decoder_error (&data->error, ERROR_FATAL, 0,
		               "File too large for audio format!");
		return data;
	}

	debug ("Opened file %s", file);
	debug ("Channels: %d", data->snd_info.channels);
	debug ("Format: %08X", data->snd_info.format);
	debug ("Sample rate: %d", data->snd_info.samplerate);

	return data;
}
Exemplo n.º 14
0
static int sndfile_open_file(struct input_handle* ih, const char* filename) {
#ifdef G_OS_WIN32
  int fd;
  g_usleep(10);
  fd = input_open_fd(filename);
  if (fd < 0) return 1;
  ih->file = sf_open_fd(fd, SFM_READ, &ih->file_info, 1);
#else
  ih->file = sf_open(filename, SFM_READ, &ih->file_info);
#endif

  if (ih->file) {
    return 0;
  } else {
#ifdef G_OS_WIN32
    _close(fd);
#endif
    return 1;
  }
}
Exemplo n.º 15
0
/* If byfd is true, try to open the file with sf_open_fd */
int test(const char* filename, int byfd)
{
    SF_INFO     info;
    SNDFILE*    file;
    int         fid, flags, st;
    char        buffer [2048];

    st  = 0;

    flags = O_RDONLY;
#if (defined (WIN32) || defined (_WIN32))
    flags |= O_BINARY;
#endif

    info.format = 0;
    if (byfd) {
        fid = open(filename, flags);
        if (fid < 0) {
            fprintf(stderr, "%s:%s failed opening file %s\n", __FILE__, __func__, filename);
            return -1;
        }

        file = sf_open_fd(fid, SFM_READ, &info, SF_TRUE);
    } else {
        file = sf_open(filename, SFM_READ, &info);
    }

    if (file == NULL) {
        fprintf(stderr, "%s:%s failed opening file %s\n", __FILE__, __func__, filename);
        sf_command (file, SFC_GET_LOG_INFO, buffer, sizeof (buffer)) ;
        fprintf(stderr, "sndfile error is %s:\n", buffer);
        close(fid);
        exit(EXIT_FAILURE);
    } else {
        fprintf(stderr, "%s:%s file %s has %d frames \n", __FILE__, __func__, filename, info.frames);
    }

    sf_close(file);

    return st;
}
Exemplo n.º 16
0
struct wav_file *wav_open(const char *filename)
{
    struct wav_file *wav;

    if( !(wav = calloc(1, sizeof(struct wav_file))))
        return NULL;

    wav->file_info.format = 0;

    if(strcmp(filename, "-") == 0)
        wav->file_handle = sf_open_fd(fileno(stdin), SFM_READ, &wav->file_info, 0);
    else
        wav->file_handle = sf_open(filename, SFM_READ, &wav->file_info);

    if( !wav->file_handle)
    {
        free(wav);
        return NULL;
    }

    return wav;
}
Exemplo n.º 17
0
OGGFileAudioSink::OGGFileAudioSink(const std::string& filename, int out_count) : _count(out_count)
{
	_sfinfo.samplerate = 8000;
	_sfinfo.channels = 1;
//	_sfinfo.format = SF_FORMAT_AU | SF_FORMAT_FLOAT;
	_sfinfo.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS;
//	_sfinfo.frames = 0x7FFFFFFF;
	int valid_format = sf_format_check(&_sfinfo);
	if(!valid_format)
		std::cerr << "invalid format" << std::endl;
	if(filename == "stdout")
	{
	 	_f = sf_open_fd(1, SFM_WRITE, &_sfinfo, false);

	}
	else
	{
	 	_f = sf_open(filename.c_str(), SFM_WRITE, &_sfinfo);
	}
	if(!_f)
	{
		std::cerr << "sf_open failed" << std::cerr;
	}
}
Exemplo n.º 18
0
/// Read the data portion of the block file using libsndfile.  Convert it
/// to the given format if it is not already.
///
/// @param data   The buffer where the data will be stored
/// @param format The format the data will be stored in
/// @param start  The offset in this block file
/// @param len    The number of samples to read
int LegacyBlockFile::ReadData(samplePtr data, sampleFormat format,
                              sampleCount start, sampleCount len)
{
   SF_INFO info;

   memset(&info, 0, sizeof(info));

   switch(mFormat) {
   case int16Sample:
      info.format =
         SF_FORMAT_RAW | SF_FORMAT_PCM_16 | SF_ENDIAN_CPU;
      break;
   default:
   case floatSample:
      info.format =
         SF_FORMAT_RAW | SF_FORMAT_FLOAT | SF_ENDIAN_CPU;
      break;
   case int24Sample:
      info.format = SF_FORMAT_RAW | SF_FORMAT_PCM_32 | SF_ENDIAN_CPU;
      break;
   }
   info.samplerate = 44100; // Doesn't matter
   info.channels = 1;
   info.frames = mLen + (mSummaryInfo.totalSummaryBytes /
                         SAMPLE_SIZE(mFormat));

   wxFile f;   // will be closed when it goes out of scope
   SNDFILE *sf = NULL;

   if (f.Open(mFileName.GetFullPath())) {
      // Even though there is an sf_open() that takes a filename, use the one that
      // takes a file descriptor since wxWidgets can open a file with a Unicode name and
      // libsndfile can't (under Windows).
      sf = sf_open_fd(f.fd(), SFM_READ, &info, FALSE);
   }

   {
      Maybe<wxLogNull> silence{};
      if (mSilentLog)
         silence.create();

      if (!sf){

         memset(data, 0, SAMPLE_SIZE(format)*len);

         mSilentLog = TRUE;

         return len;
      }
   }
   mSilentLog=FALSE;

   sf_count_t seekstart = start +
         (mSummaryInfo.totalSummaryBytes / SAMPLE_SIZE(mFormat));
   sf_seek(sf, seekstart , SEEK_SET);

   SampleBuffer buffer(len, floatSample);
   int framesRead = 0;

   // If both the src and dest formats are integer formats,
   // read integers from the file (otherwise we would be
   // converting to float and back, which is unneccesary)
   if (format == int16Sample &&
       sf_subtype_is_integer(info.format)) {
      framesRead = sf_readf_short(sf, (short *)data, len);
   }else if (format == int24Sample &&
             sf_subtype_is_integer(info.format)) {
      framesRead = sf_readf_int(sf, (int *)data, len);

         // libsndfile gave us the 3 byte sample in the 3 most
      // significant bytes -- we want it in the 3 least
      // significant bytes.
      int *intPtr = (int *)data;
      for( int i = 0; i < framesRead; i++ )
         intPtr[i] = intPtr[i] >> 8;
   } else {
Exemplo n.º 19
0
static int srconv(CSOUND *csound, int argc, char **argv)
{
    MYFLT
      *input,     /* pointer to start of input buffer */
      *output,    /* pointer to start of output buffer */
      *nextIn,    /* pointer to next empty word in input */
      *nextOut,   /* pointer to next empty word in output */
      *fxval = 0, /* pointer to start of time-array for time-vary function */
      *fyval = 0, /* pointer to start of P-scale-array for time-vary func */
      *i0,        /* pointer */
      *i1;        /* pointer */

    float
      *window,    /* pointer to center of analysis window */
      *wj,        /* pointer to window */
      *wj1;       /* pointer to window */

    int
      M = 2401,   /* length of window impulse response */
      N = 120,    /* length of sinc period */
      L = 120,    /* internal sample rate is L*Rin */
      m,          /* current input sample in buffer */
      o,          /* current input at L*Rin mod L */
      del,        /* increment */
      WinLen,     /* half-length of window at L*Rin */
      wLen,       /* half-length of window at Rin */
      jMin,       /* initial offset in window */
      mMax;       /* maximum valid m */

    long
      n,                        /* current input sample */
      nMax = 2000000000;        /* last input sample (unless EOF) */

    MYFLT
      beta = FL(6.8),           /* parameter for Kaiser window */
      sum,                      /* scale factor for renormalizing windows */
      fdel,                     /* float del */
      idel,                     /* float del */
      fo,                       /* float o */
      of,                       /* fractional o */
      fL = (MYFLT) L,           /* float L */
      iw,                       /* interpolated window */
      tvx0 = 0,                 /* current x value of time-var function */
      tvx1 = 0,                 /* next x value of time-var function */
      tvdx,                     /* tvx1 - tvx0 */
      tvy0 = 0,                 /* current y value of time-var function */
      tvy1 = 0,                 /* next y value of time-var function */
      tvdy,                     /* tvy1 - tvy0 */
      tvslope = 0,              /* tvdy / tvdx */
      time,                     /* n / Rin */
      invRin,                   /* 1. / Rin */
      P = FL(0.0),              /* Rin / Rout */
      Rin = FL(0.0),            /* input sampling rate */
      Rout = FL(0.0);           /* output sample rate */

    int
      i,k,                      /* index variables */
      nread,                    /* number of bytes read */
      tvflg = 0,                /* flag for time-varying time-scaling */
      tvnxt = 0,                /* counter for stepping thru time-var func */
      tvlen,                    /* length of time-varying function */
      Chans = 1,                /* number of channels */
      chan,                     /* current channel */
      Q = 2;                    /* quality factor */

    FILE        *tvfp = NULL;   /* time-vary function file */
    SOUNDIN     *p;
    int         channel = ALLCHNLS;
    MYFLT       beg_time = FL(0.0), input_dur = FL(0.0), sr = FL(0.0);
    char        *infile = NULL, *bfile = NULL;
    SNDFILE     *inf = NULL;
    char        c, *s;
    const char  *envoutyp;
    char        outformch = 's';
    unsigned    outbufsiz = 0U;
    SNDFILE     *outfd = NULL;
    OPARMS      O;
    int         block = 0;
    char        err_msg[256];

    O.outformat = AE_SHORT;
    /* csound->e0dbfs = csound->dbfs_to_float = FL(1.0);*/

    if ((envoutyp = csound->GetEnv(csound, "SFOUTYP")) != NULL) {
      if (strcmp(envoutyp, "AIFF") == 0)
        O.filetyp = TYP_AIFF;
      else if (strcmp(envoutyp, "WAV") == 0)
        O.filetyp = TYP_WAV;
      else if (strcmp(envoutyp, "IRCAM") == 0)
        O.filetyp = TYP_IRCAM;
      else {
        snprintf(err_msg, 256, Str("%s not a recognized SFOUTYP env setting"),
                envoutyp);
        dieu(csound, err_msg);
        return -1;
      }
    }

    /* call getopt to interpret commandline */

    ++argv;
    while (--argc > 0) {
      s = *argv++;
      if (*s++ == '-') {                /* read all flags:  */
        while ((c = *s++) != '\0') {
          switch (c) {
          case 'o':
            FIND(Str("no outfilename"))
            O.outfilename = s;         /* soundout name */
            for ( ; *s != '\0'; s++) ;
            if (strcmp(O.outfilename, "stdin") == 0) {
              csound->ErrorMsg(csound, Str("-o cannot be stdin"));
              return -1;
            }
#if defined WIN32
            if (strcmp(O.outfilename, "stdout") == 0) {
              csound->ErrorMsg(csound, Str("stdout audio not supported"));
              return -1;
            }
#endif
            break;
          case 'A':
            O.filetyp = TYP_AIFF;      /* AIFF output request*/
            break;
          case 'J':
            O.filetyp = TYP_IRCAM;     /* IRCAM output request */
            break;
          case 'W':
            O.filetyp = TYP_WAV;       /* WAV output request */
            break;
          case 'h':
            O.filetyp = TYP_RAW;       /* skip sfheader  */
            break;
          case 'c':
          case '8':
          case 'a':
          case 'u':
          case 's':
          case 'l':
          case '3':
          case 'f':
            outformch = set_output_format(csound, c, outformch, &O);
            break;
          case 'R':
            O.rewrt_hdr = 1;
            break;
          case 'H':
            if (isdigit(*s)) {
              int n;
              sscanf(s, "%d%n", &O.heartbeat, &n);
              s += n;
            }
            else O.heartbeat = 1;
            break;
          case 'N':
            O.ringbell = 1;        /* notify on completion */
            break;
          case 'Q':
            FIND(Str("No Q argument"))
            sscanf(s,"%d", &Q);
            while (*++s);
            break;
          case 'P':
            FIND(Str("No P argument"))
#if defined(USE_DOUBLE)
            csound->sscanf(s,"%lf", &P);
#else
            csound->sscanf(s,"%f", &P);
#endif
            while (*++s);
            break;
          case 'r':
            FIND(Str("No r argument"))
#if defined(USE_DOUBLE)
            csound->sscanf(s,"%lf", &Rout);
#else
            csound->sscanf(s,"%f", &Rout);
#endif
            while (*++s);
            break;
          case 'i':
            FIND(Str("No break file"))
            tvflg = 1;
            bfile = s;
            while ((*s++)) {}; s--;
            break;
          default:
            csound->Message(csound, Str("Looking at %c\n"), c);
            usage(csound);    /* this exits with error */
            return -1;
          }
        }
      }
      else if (infile == NULL) {
        infile = --s;
        csound->Message(csound, Str("Infile set to %s\n"), infile);
      }
      else {
        csound->Message(csound, Str("End with %s\n"), s);
        usage(csound);
        return -1;
      }
    }
    if (infile == NULL) {
      csound->Message(csound, Str("No input given\n"));
      usage(csound);
      return -1;
    }
    if ((inf = csound->SAsndgetset(csound, infile, &p, &beg_time,
                                   &input_dur, &sr, channel)) == NULL) {
      csound->ErrorMsg(csound, Str("error while opening %s"), infile);
      return -1;
    }
    if (Rin == FL(0.0))
      Rin = (MYFLT)p->sr;
    if (Chans == 0)
      Chans = (int) p->nchanls;
    if (Chans == 0)
      Chans = 1;

    if ((P != FL(0.0)) && (Rout != FL(0.0))) {
      strncpy(err_msg, Str("srconv: cannot specify both -r and -P"), 256);
      goto err_rtn_msg;
    }
    if (P != FL(0.0))
      Rout = Rin / P;
    else if (Rout == FL(0.0))
      Rout = Rin;

    if (tvflg) {
      P = FL(0.0);        /* will be reset to max in time-vary function */
      if ((tvfp = fopen(bfile, "r")) == NULL) {
        strncpy(err_msg,
                Str("srconv: cannot open time-vary function file"), 256);
        goto err_rtn_msg;
      }
      /* register file to be closed by csoundReset() */
      (void) csound->CreateFileHandle(csound, &tvfp, CSFILE_STD, bfile);
      if (UNLIKELY(fscanf(tvfp, "%d", &tvlen) != 1))
        csound->Message(csound, Str("Read failure\n"));
      if(tvlen <= 0) {
            strncpy(err_msg, Str("srconv: tvlen <= 0 "), 256);
            goto err_rtn_msg;
       }
      fxval = (MYFLT*) csound->Malloc(csound, tvlen * sizeof(MYFLT));
      fyval = (MYFLT*) csound->Malloc(csound, tvlen * sizeof(MYFLT));
      i0 = fxval;
      i1 = fyval;
      for (i = 0; i < tvlen; i++, i0++, i1++) {
#ifdef USE_DOUBLE
        if ((fscanf(tvfp, "%lf %lf", i0, i1)) != 2)
#else
        if ((fscanf(tvfp, "%f %f", i0, i1)) != 2)
#endif
          {
            strncpy(err_msg, Str("srconv: too few x-y pairs "
                                 "in time-vary function file"), 256);
            goto err_rtn_msg;
          }
        if (*i1 > P)
          P = *i1;
      }
      Rout = Rin / P;    /* this is min Rout */
      tvx0 = fxval[0];
      tvx1 = fxval[1];
      tvy0 = fyval[0];
      tvy1 = fyval[1];
      tvdx = tvx1 - tvx0;
      if (tvx0 != FL(0.0)) {
        strncpy(err_msg, Str("srconv: first x value "
                             "in time-vary function must be 0"), 256);
        goto err_rtn_msg;
      }
      if (tvy0 <= FL(0.0)) {
        strncpy(err_msg, Str("srconv: invalid initial y value "
                             "in time-vary function"),256);
        goto err_rtn_msg;
      }
      if (tvdx <= FL(0.0)) {
        strncpy(err_msg,
                       Str("srconv: invalid x values in time-vary function"),
                       256);
        goto err_rtn_msg;
      }
      tvdy = tvy1 - tvy0;
      tvslope = tvdy / tvdx;
      tvnxt = 1;
    }
    /* This is not right *********  */
    if (P != FL(0.0)) {
      csound->SetUtilSr(csound,Rin);
    }
    if (P == FL(0.0)) {
      csound->SetUtilSr(csound,Rout);
    }

    if (O.outformat == 0)
      O.outformat = AE_SHORT;//p->format;
    O.sfsampsize = csound->sfsampsize(FORMAT2SF(O.outformat));
    if (O.filetyp == TYP_RAW) {
      O.sfheader = 0;
      O.rewrt_hdr = 0;
    }
    else
      O.sfheader = 1;
#ifdef NeXT
    if (O.outfilename == NULL && !O.filetyp)
      O.outfilename = "test.snd";
    else if (O.outfilename == NULL)
      O.outfilename = "test";
#else
    if (O.outfilename == NULL) {
      if (O.filetyp == TYP_WAV)
        O.outfilename = "test.wav";
      else if (O.filetyp == TYP_AIFF)
        O.outfilename = "test.aif";
      else
        O.outfilename = "test";
    }
#endif
    {
      SF_INFO sfinfo;
      char    *name;
      memset(&sfinfo, 0, sizeof(SF_INFO));
      sfinfo.samplerate = (int) ((double) Rout + 0.5);
      sfinfo.channels = (int) p->nchanls;
      //printf("filetyp=%x outformat=%x\n", O.filetyp, O.outformat);
      sfinfo.format = TYPE2SF(O.filetyp) | FORMAT2SF(O.outformat);
      if (strcmp(O.outfilename, "stdout") != 0) {
        name = csound->FindOutputFile(csound, O.outfilename, "SFDIR");
        if (name == NULL) {
          snprintf(err_msg, 256, Str("cannot open %s."), O.outfilename);
          goto err_rtn_msg;
        }
        outfd = sf_open(name, SFM_WRITE, &sfinfo);
        if (outfd != NULL)
          csound->NotifyFileOpened(csound, name,
                                   csound->type2csfiletype(O.filetyp,
                                                           O.outformat),
                                   1, 0);
        else {
          snprintf(err_msg, 256, Str("libsndfile error: %s\n"), sf_strerror(NULL));
          goto err_rtn_msg;
        }
        csound->Free(csound, name);
      }
      else
        outfd = sf_open_fd(1, SFM_WRITE, &sfinfo, 1);
      if (outfd == NULL) {
        snprintf(err_msg, 256, Str("cannot open %s."), O.outfilename);
        goto err_rtn_msg;
      }
      /* register file to be closed by csoundReset() */
      (void) csound->CreateFileHandle(csound, &outfd, CSFILE_SND_W,
                                      O.outfilename);
      sf_command(outfd, SFC_SET_CLIPPING, NULL, SF_TRUE);
    }
    csound->SetUtilSr(csound, (MYFLT)p->sr);
    csound->SetUtilNchnls(csound, Chans = p->nchanls);

    outbufsiz = OBUF * O.sfsampsize;                   /* calc outbuf size */
    csound->Message(csound, Str("writing %d-byte blks of %s to %s"),
                    outbufsiz, csound->getstrformat(O.outformat),
                    O.outfilename);
    csound->Message(csound, " (%s)\n", csound->type2string(O.filetyp));

 /* this program performs arbitrary sample-rate conversion
    with high fidelity.  the method is to step through the
    input at the desired sampling increment, and to compute
    the output points as appropriately weighted averages of
    the surrounding input points.  there are two cases to
    consider: 1) sample rates are in a small-integer ratio -
    weights are obtained from table, 2) sample rates are in
    a large-integer ratio - weights are linearly
    interpolated from table.  */

 /* calculate increment: if decimating, then window is impulse response of low-
    pass filter with cutoff frequency at half of Rout; if interpolating,
    then window is ipulse response of lowpass filter with cutoff frequency
    at half of Rin. */

    fdel = ((MYFLT) (L * Rin) / Rout);
    del = (int) ((double) fdel + 0.5);
    idel = (MYFLT) del;
    if (del > L)
      N = del;
    if ((Q >= 1) && (Q <= 8))
      M = Q * N * 10 + 1;
    if (tvflg)
      fdel = tvy0 * L;

    invRin  =  FL(1.0) / Rin;

    /* make window: the window is the product of a kaiser and a sin(x)/x */
    window = (float*) csound->Calloc(csound, (size_t) (M + 2) * sizeof(float));
    WinLen = (M-1)/2;
    window += WinLen;
    wLen = (M/2 - L) / L;

    kaiser(M, window, WinLen, 1, (double) beta);

    for (i = 1; i <= WinLen; i++) {
      double  tmp = (double) N;
      tmp = tmp * sin(PI * (double) i / tmp) / (PI * (double) i);
      window[i] = (float) ((double) window[i] * tmp);
    }

    if (Rout < Rin) {
#if 0
      sum = (MYFLT) window[0];
      for (i = L-1; i <= WinLen; i += L)
        sum += (MYFLT) window[i];
      sum = FL(2.0) / sum;
#else
      sum = Rout / (Rin * (MYFLT) window[0]);
#endif
    }
    else
      sum = FL(1.0) / (MYFLT) window[0];

    window[0] = (float) ((double) window[0] * (double) sum);
    for (i = 1; i <= WinLen; i++) {
      window[i] = (float) ((double) window[i] * (double) sum);
      *(window - i) = window[i];
    }

    window[WinLen + 1] = 0.0f;

 /* set up input buffer:  nextIn always points to the next empty
    word in the input buffer.  If the buffer is full, then
    nextIn jumps back to the beginning, and the old values
    are written over. */

    input = (MYFLT*) csound->Calloc(csound, (size_t) IBUF * sizeof(MYFLT));

 /* set up output buffer:  nextOut always points to the next empty
    word in the output buffer.  If the buffer is full, then
    it is flushed, and nextOut jumps back to the beginning. */

    output = (MYFLT*) csound->Calloc(csound, (size_t) OBUF * sizeof(MYFLT));
    nextOut = output;

 /* initialization: */

    nread = csound->getsndin(csound, inf, input, IBUF2, p);
    for(i=0; i < nread; i++)
       input[i] *= 1.0/csound->Get0dBFS(csound);
    nMax = (long)(input_dur * p->sr);
    nextIn = input + nread;
    for (i = nread; i < IBUF2; i++)
      *(nextIn++) = FL(0.0);
    jMin = -(wLen + 1) * L;
    mMax = IBUF2;
    o = n = m = 0;
    fo = FL(0.0);

 /* main loop:   If nMax is not specified it is assumed to be very large
    and then readjusted when read detects the end of input. */

    while (n < nMax) {

      time = n * invRin;

      /* case 1:  (Rin / Rout) * 120 = integer  */

      if ((tvflg == 0) && (idel == fdel)) {
        /* apply window (window is sampled at L * Rin) */

        for (chan = 0; chan < Chans; chan++) {
          *nextOut = FL(0.0);
          k = Chans * (m - wLen) + chan - Chans;
          if (k < 0)
            k += IBUF;
          wj = window + jMin - o;
          for (i = -wLen; i <= wLen+1; i++){
            wj += L;
            k += Chans;
            if (k >= IBUF)
              k -= IBUF;
            *nextOut += (MYFLT) *wj * *(input + k);
          }
          nextOut++;
          if (nextOut >= (output + OBUF)) {
            nextOut = output;
            writebuffer(csound, output, &block, outfd, OBUF, &O);
          }
        }

        /* move window (window advances by del samples at L*Rin sample rate) */

        o += del;
        while (o >= L) {
          o -= L;
          n++;
          m++;
          if ((Chans * (m + wLen + 1)) >= mMax) {
            if (!csound->CheckEvents(csound))
              csound->LongJmp(csound, 1);
            mMax += IBUF2;
            if (nextIn >= (input + IBUF))
              nextIn = input;
            nread = csound->getsndin(csound, inf, nextIn, IBUF2, p);
            for(i=0; i < nread; i++)
               input[i] *= 1.0/csound->Get0dBFS(csound);
            nextIn += nread;
            if (nread < IBUF2)
              nMax = n + wLen + (nread / Chans) + 1;
            for (i = nread; i < IBUF2; i++)
              *(nextIn++) = FL(0.0);
          }
          if ((Chans * m) >= IBUF) {
            m = 0;
            mMax = IBUF2;
          }
        }
      }

      /* case 2: (Rin / Rout) * 120 = non-integer constant */

      else {

        /* apply window (window values are linearly interpolated) */

        for (chan = 0; chan < Chans; chan++) {
          *nextOut = FL(0.0);
          o = (int)fo;
          of = fo - o;
          wj = window + jMin - o;
          wj1 = wj + 1;
          k = Chans * (m - wLen) + chan - Chans;
          if (k < 0)
            k += IBUF;
          for (i = -wLen; i <= wLen+1; i++) {
            wj += L;
            wj1 += L;
            k += Chans;
            if (k >= IBUF)
              k -= IBUF;
            iw = (MYFLT) *wj + of * ((MYFLT) *wj1 - (MYFLT) *wj);
            *nextOut += iw * *(input + k);
          }
          nextOut++;
          if (nextOut >= (output + OBUF)) {
            nextOut = output;
            writebuffer(csound, output, &block, outfd, OBUF, &O);
          }
        }

        /* move window */

        fo += fdel;
        while (fo >= fL) {
          fo -= fL;
          n++;
          m++;
          if ((Chans * (m + wLen + 1)) >= mMax) {
            if (!csound->CheckEvents(csound))
              csound->LongJmp(csound, 1);
            mMax += IBUF2;
            if (nextIn >= (input + IBUF))
              nextIn = input;
            nread = csound->getsndin(csound, inf, nextIn, IBUF2, p);
            for(i=0; i < nread; i++)
               input[i] *= 1.0/csound->Get0dBFS(csound);
            nextIn += nread;
            if (nread < IBUF2)
              nMax = n + wLen + (nread / Chans) + 1;
            for (i = nread; i < IBUF2; i++)
              *(nextIn++) = FL(0.0);
          }
          if ((Chans * m) >= IBUF) {
            m = 0;
            mMax = IBUF2;
          }
        }

        if (tvflg && (time > FL(0.0))) {
          while (tvflg && (time >= tvx1)) {
            if (++tvnxt >= tvlen)
              tvflg = 0;
            else {
              tvx0 = tvx1;
              tvx1 = fxval[tvnxt];
              tvy0 = tvy1;
              tvy1 = fyval[tvnxt];
              tvdx = tvx1 - tvx0;
              if (tvdx <= FL(0.0)) {
                strncpy(err_msg, Str("srconv: invalid x values "
                                     "in time-vary function"), 256);
                goto err_rtn_msg;
              }
              tvdy = tvy1 - tvy0;
              tvslope = tvdy / tvdx;
            }
          }
          P = tvy0 + tvslope * (time - tvx0);
          fdel = (MYFLT) L * P;
        }
      }

    }
    nread = nextOut - output;
    writebuffer(csound, output, &block, outfd, nread, &O);
    csound->Message(csound, "\n\n");
    if (O.ringbell)
      csound->MessageS(csound, CSOUNDMSG_REALTIME, "\a");
    return 0;

 err_rtn_msg:
    csound->ErrorMsg(csound, err_msg);
    return -1;
}
Exemplo n.º 20
0
int main(int argc, char *argv[]) {
    pa_mainloop* m = NULL;
    int ret = 1, c;
    char *bn, *server = NULL;
    pa_time_event *time_event = NULL;
    const char *filename = NULL;

    static const struct option long_options[] = {
        {"record",       0, NULL, 'r'},
        {"playback",     0, NULL, 'p'},
        {"device",       1, NULL, 'd'},
        {"server",       1, NULL, 's'},
        {"client-name",  1, NULL, 'n'},
        {"stream-name",  1, NULL, ARG_STREAM_NAME},
        {"version",      0, NULL, ARG_VERSION},
        {"help",         0, NULL, 'h'},
        {"verbose",      0, NULL, 'v'},
        {"volume",       1, NULL, ARG_VOLUME},
        {"rate",         1, NULL, ARG_SAMPLERATE},
        {"format",       1, NULL, ARG_SAMPLEFORMAT},
        {"channels",     1, NULL, ARG_CHANNELS},
        {"channel-map",  1, NULL, ARG_CHANNELMAP},
        {"fix-format",   0, NULL, ARG_FIX_FORMAT},
        {"fix-rate",     0, NULL, ARG_FIX_RATE},
        {"fix-channels", 0, NULL, ARG_FIX_CHANNELS},
        {"no-remap",     0, NULL, ARG_NO_REMAP},
        {"no-remix",     0, NULL, ARG_NO_REMIX},
        {"latency",      1, NULL, ARG_LATENCY},
        {"process-time", 1, NULL, ARG_PROCESS_TIME},
        {"property",     1, NULL, ARG_PROPERTY},
        {"raw",          0, NULL, ARG_RAW},
        {"file-format",  2, NULL, ARG_FILE_FORMAT},
        {"list-file-formats", 0, NULL, ARG_LIST_FILE_FORMATS},
        {"latency-msec", 1, NULL, ARG_LATENCY_MSEC},
        {"process-time-msec", 1, NULL, ARG_PROCESS_TIME_MSEC},
        {NULL,           0, NULL, 0}
    };

    setlocale(LC_ALL, "");
    bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR);

    bn = pa_path_get_filename(argv[0]);

    if (strstr(bn, "play")) {
        mode = PLAYBACK;
        raw = FALSE;
    } else if (strstr(bn, "record")) {
        mode = RECORD;
        raw = FALSE;
    } else if (strstr(bn, "cat")) {
        mode = PLAYBACK;
        raw = TRUE;
    } if (strstr(bn, "rec") || strstr(bn, "mon")) {
        mode = RECORD;
        raw = TRUE;
    }

    proplist = pa_proplist_new();

    while ((c = getopt_long(argc, argv, "rpd:s:n:hv", long_options, NULL)) != -1) {

        switch (c) {
            case 'h' :
                help(bn);
                ret = 0;
                goto quit;

            case ARG_VERSION:
                printf(_("pacat %s\n"
                         "Compiled with libpulse %s\n"
                         "Linked with libpulse %s\n"),
                       PACKAGE_VERSION,
                       pa_get_headers_version(),
                       pa_get_library_version());
                ret = 0;
                goto quit;

            case 'r':
                mode = RECORD;
                break;

            case 'p':
                mode = PLAYBACK;
                break;

            case 'd':
                pa_xfree(device);
                device = pa_xstrdup(optarg);
                break;

            case 's':
                pa_xfree(server);
                server = pa_xstrdup(optarg);
                break;

            case 'n': {
                char *t;

                if (!(t = pa_locale_to_utf8(optarg)) ||
                    pa_proplist_sets(proplist, PA_PROP_APPLICATION_NAME, t) < 0) {

                    pa_log(_("Invalid client name '%s'"), t ? t : optarg);
                    pa_xfree(t);
                    goto quit;
                }

                pa_xfree(t);
                break;
            }

            case ARG_STREAM_NAME: {
                char *t;

                if (!(t = pa_locale_to_utf8(optarg)) ||
                    pa_proplist_sets(proplist, PA_PROP_MEDIA_NAME, t) < 0) {

                    pa_log(_("Invalid stream name '%s'"), t ? t : optarg);
                    pa_xfree(t);
                    goto quit;
                }

                pa_xfree(t);
                break;
            }

            case 'v':
                verbose = 1;
                break;

            case ARG_VOLUME: {
                int v = atoi(optarg);
                volume = v < 0 ? 0U : (pa_volume_t) v;
                volume_is_set = TRUE;
                break;
            }

            case ARG_CHANNELS:
                sample_spec.channels = (uint8_t) atoi(optarg);
                sample_spec_set = TRUE;
                break;

            case ARG_SAMPLEFORMAT:
                sample_spec.format = pa_parse_sample_format(optarg);
                sample_spec_set = TRUE;
                break;

            case ARG_SAMPLERATE:
                sample_spec.rate = (uint32_t) atoi(optarg);
                sample_spec_set = TRUE;
                break;

            case ARG_CHANNELMAP:
                if (!pa_channel_map_parse(&channel_map, optarg)) {
                    pa_log(_("Invalid channel map '%s'"), optarg);
                    goto quit;
                }

                channel_map_set = TRUE;
                break;

            case ARG_FIX_CHANNELS:
                flags |= PA_STREAM_FIX_CHANNELS;
                break;

            case ARG_FIX_RATE:
                flags |= PA_STREAM_FIX_RATE;
                break;

            case ARG_FIX_FORMAT:
                flags |= PA_STREAM_FIX_FORMAT;
                break;

            case ARG_NO_REMIX:
                flags |= PA_STREAM_NO_REMIX_CHANNELS;
                break;

            case ARG_NO_REMAP:
                flags |= PA_STREAM_NO_REMAP_CHANNELS;
                break;

            case ARG_LATENCY:
                if (((latency = (size_t) atoi(optarg))) <= 0) {
                    pa_log(_("Invalid latency specification '%s'"), optarg);
                    goto quit;
                }
                break;

            case ARG_PROCESS_TIME:
                if (((process_time = (size_t) atoi(optarg))) <= 0) {
                    pa_log(_("Invalid process time specification '%s'"), optarg);
                    goto quit;
                }
                break;

            case ARG_LATENCY_MSEC:
                if (((latency_msec = (int32_t) atoi(optarg))) <= 0) {
                    pa_log(_("Invalid latency specification '%s'"), optarg);
                    goto quit;
                }
                break;

            case ARG_PROCESS_TIME_MSEC:
                if (((process_time_msec = (int32_t) atoi(optarg))) <= 0) {
                    pa_log(_("Invalid process time specification '%s'"), optarg);
                    goto quit;
                }
                break;

            case ARG_PROPERTY: {
                char *t;

                if (!(t = pa_locale_to_utf8(optarg)) ||
                    pa_proplist_setp(proplist, t) < 0) {

                    pa_xfree(t);
                    pa_log(_("Invalid property '%s'"), optarg);
                    goto quit;
                }

                pa_xfree(t);
                break;
            }

            case ARG_RAW:
                raw = TRUE;
                break;

            case ARG_FILE_FORMAT:
                raw = FALSE;

                if (optarg) {
                    if ((file_format = pa_sndfile_format_from_string(optarg)) < 0) {
                        pa_log(_("Unknown file format %s."), optarg);
                        goto quit;
                    }
                }

                raw = FALSE;
                break;

            case ARG_LIST_FILE_FORMATS:
                pa_sndfile_dump_formats();
                ret = 0;
                goto quit;

            default:
                goto quit;
        }
    }

    if (!pa_sample_spec_valid(&sample_spec)) {
        pa_log(_("Invalid sample specification"));
        goto quit;
    }

    if (optind+1 == argc) {
        int fd;

        filename = argv[optind];

        if ((fd = open(argv[optind], mode == PLAYBACK ? O_RDONLY : O_WRONLY|O_TRUNC|O_CREAT, 0666)) < 0) {
            pa_log(_("open(): %s"), strerror(errno));
            goto quit;
        }

        if (dup2(fd, mode == PLAYBACK ? STDIN_FILENO : STDOUT_FILENO) < 0) {
            pa_log(_("dup2(): %s"), strerror(errno));
            goto quit;
        }

        pa_close(fd);

    } else if (optind+1 <= argc) {
        pa_log(_("Too many arguments."));
        goto quit;
    }

    if (!raw) {
        SF_INFO sfi;
        pa_zero(sfi);

        if (mode == RECORD) {
            /* This might patch up the sample spec */
            if (pa_sndfile_write_sample_spec(&sfi, &sample_spec) < 0) {
                pa_log(_("Failed to generate sample specification for file."));
                goto quit;
            }

            /* Transparently upgrade classic .wav to wavex for multichannel audio */
            if (file_format <= 0) {
                if ((sample_spec.channels == 2 && (!channel_map_set || (channel_map.map[0] == PA_CHANNEL_POSITION_LEFT &&
                                                                        channel_map.map[1] == PA_CHANNEL_POSITION_RIGHT))) ||
                    (sample_spec.channels == 1 && (!channel_map_set || (channel_map.map[0] == PA_CHANNEL_POSITION_MONO))))
                    file_format = SF_FORMAT_WAV;
                else
                    file_format = SF_FORMAT_WAVEX;
            }

            sfi.format |= file_format;
        }

        if (!(sndfile = sf_open_fd(mode == RECORD ? STDOUT_FILENO : STDIN_FILENO,
                                   mode == RECORD ? SFM_WRITE : SFM_READ,
                                   &sfi, 0))) {
            pa_log(_("Failed to open audio file."));
            goto quit;
        }

        if (mode == PLAYBACK) {
            if (sample_spec_set)
                pa_log(_("Warning: specified sample specification will be overwritten with specification from file."));

            if (pa_sndfile_read_sample_spec(sndfile, &sample_spec) < 0) {
                pa_log(_("Failed to determine sample specification from file."));
                goto quit;
            }
            sample_spec_set = TRUE;

            if (!channel_map_set) {
                /* Allow the user to overwrite the channel map on the command line */
                if (pa_sndfile_read_channel_map(sndfile, &channel_map) < 0) {
                    if (sample_spec.channels > 2)
                        pa_log(_("Warning: Failed to determine channel map from file."));
                } else
                    channel_map_set = TRUE;
            }
        }
    }

    if (!channel_map_set)
        pa_channel_map_init_extend(&channel_map, sample_spec.channels, PA_CHANNEL_MAP_DEFAULT);

    if (!pa_channel_map_compatible(&channel_map, &sample_spec)) {
        pa_log(_("Channel map doesn't match sample specification"));
        goto quit;
    }

    if (!raw) {
        pa_proplist *sfp;

        if (mode == PLAYBACK)
            readf_function = pa_sndfile_readf_function(&sample_spec);
        else {
            if (pa_sndfile_write_channel_map(sndfile, &channel_map) < 0)
                pa_log(_("Warning: failed to write channel map to file."));

            writef_function = pa_sndfile_writef_function(&sample_spec);
        }

        /* Fill in libsndfile prop list data */
        sfp = pa_proplist_new();
        pa_sndfile_init_proplist(sndfile, sfp);
        pa_proplist_update(proplist, PA_UPDATE_MERGE, sfp);
        pa_proplist_free(sfp);
    }

    if (verbose) {
        char tss[PA_SAMPLE_SPEC_SNPRINT_MAX], tcm[PA_CHANNEL_MAP_SNPRINT_MAX];

        pa_log(_("Opening a %s stream with sample specification '%s' and channel map '%s'."),
                mode == RECORD ? _("recording") : _("playback"),
                pa_sample_spec_snprint(tss, sizeof(tss), &sample_spec),
                pa_channel_map_snprint(tcm, sizeof(tcm), &channel_map));
    }

    /* Fill in client name if none was set */
    if (!pa_proplist_contains(proplist, PA_PROP_APPLICATION_NAME)) {
        char *t;

        if ((t = pa_locale_to_utf8(bn))) {
            pa_proplist_sets(proplist, PA_PROP_APPLICATION_NAME, t);
            pa_xfree(t);
        }
    }

    /* Fill in media name if none was set */
    if (!pa_proplist_contains(proplist, PA_PROP_MEDIA_NAME)) {
        const char *t;

        if ((t = filename) ||
            (t = pa_proplist_gets(proplist, PA_PROP_APPLICATION_NAME)))
            pa_proplist_sets(proplist, PA_PROP_MEDIA_NAME, t);
    }

    /* Set up a new main loop */
    if (!(m = pa_mainloop_new())) {
        pa_log(_("pa_mainloop_new() failed."));
        goto quit;
    }

    mainloop_api = pa_mainloop_get_api(m);

    pa_assert_se(pa_signal_init(mainloop_api) == 0);
    pa_signal_new(SIGINT, exit_signal_callback, NULL);
    pa_signal_new(SIGTERM, exit_signal_callback, NULL);
#ifdef SIGUSR1
    pa_signal_new(SIGUSR1, sigusr1_signal_callback, NULL);
#endif
    pa_disable_sigpipe();

    if (raw) {
        if (!(stdio_event = mainloop_api->io_new(mainloop_api,
                                                 mode == PLAYBACK ? STDIN_FILENO : STDOUT_FILENO,
                                                 mode == PLAYBACK ? PA_IO_EVENT_INPUT : PA_IO_EVENT_OUTPUT,
                                                 mode == PLAYBACK ? stdin_callback : stdout_callback, NULL))) {
            pa_log(_("io_new() failed."));
            goto quit;
        }
    }

    /* Create a new connection context */
    if (!(context = pa_context_new_with_proplist(mainloop_api, NULL, proplist))) {
        pa_log(_("pa_context_new() failed."));
        goto quit;
    }

    pa_context_set_state_callback(context, context_state_callback, NULL);

    /* Connect the context */
    if (pa_context_connect(context, server, 0, NULL) < 0) {
        pa_log(_("pa_context_connect() failed: %s"), pa_strerror(pa_context_errno(context)));
        goto quit;
    }

    if (verbose) {
        if (!(time_event = pa_context_rttime_new(context, pa_rtclock_now() + TIME_EVENT_USEC, time_event_callback, NULL))) {
            pa_log(_("pa_context_rttime_new() failed."));
            goto quit;
        }
    }

    /* Run the main loop */
    if (pa_mainloop_run(m, &ret) < 0) {
        pa_log(_("pa_mainloop_run() failed."));
        goto quit;
    }

quit:
    if (stream)
        pa_stream_unref(stream);

    if (context)
        pa_context_unref(context);

    if (stdio_event) {
        pa_assert(mainloop_api);
        mainloop_api->io_free(stdio_event);
    }

    if (time_event) {
        pa_assert(mainloop_api);
        mainloop_api->time_free(time_event);
    }

    if (m) {
        pa_signal_done();
        pa_mainloop_free(m);
    }

    pa_xfree(buffer);

    pa_xfree(server);
    pa_xfree(device);

    if (sndfile)
        sf_close(sndfile);

    if (proplist)
        pa_proplist_free(proplist);

    return ret;
}
Exemplo n.º 21
0
/// Read the data portion of the block file using libsndfile.  Convert it
/// to the given format if it is not already.
///
/// @param data   The buffer where the data will be stored
/// @param format The format the data will be stored in
/// @param start  The offset in this block file
/// @param len    The number of samples to read
int SimpleBlockFile::ReadData(samplePtr data, sampleFormat format,
                        sampleCount start, sampleCount len)
{
   if (mCache.active)
   {
      //wxLogDebug("SimpleBlockFile::ReadData(): Data are already in cache.");

      if (len > mLen - start)
         len = mLen - start;
      CopySamples(
         (samplePtr)(((char*)mCache.sampleData) +
            start * SAMPLE_SIZE(mCache.format)),
         mCache.format, data, format, len);
      return len;
   } else
   {
      //wxLogDebug("SimpleBlockFile::ReadData(): Reading data from disk.");

      SF_INFO info;
      wxFile f;   // will be closed when it goes out of scope
      SNDFILE *sf = NULL;
      {
         Maybe<wxLogNull> silence{};
         if (mSilentLog)
            silence.create();

         memset(&info, 0, sizeof(info));

         if (f.Open(mFileName.GetFullPath())) {
            // Even though there is an sf_open() that takes a filename, use the one that
            // takes a file descriptor since wxWidgets can open a file with a Unicode name and
            // libsndfile can't (under Windows).
            sf = sf_open_fd(f.fd(), SFM_READ, &info, FALSE);
         }

         if (!sf) {

            memset(data, 0, SAMPLE_SIZE(format)*len);

            mSilentLog = TRUE;

            return len;
         }
      }
      mSilentLog=FALSE;

      sf_seek(sf, start, SEEK_SET);
      SampleBuffer buffer(len, floatSample);

      int framesRead = 0;

      // If both the src and dest formats are integer formats,
      // read integers from the file (otherwise we would be
      // converting to float and back, which is unneccesary)
      if (format == int16Sample &&
          sf_subtype_is_integer(info.format)) {
         framesRead = sf_readf_short(sf, (short *)data, len);
      }
      else
      if (format == int24Sample &&
          sf_subtype_is_integer(info.format))
      {
         framesRead = sf_readf_int(sf, (int *)data, len);

         // libsndfile gave us the 3 byte sample in the 3 most
         // significant bytes -- we want it in the 3 least
         // significant bytes.
         int *intPtr = (int *)data;
         for( int i = 0; i < framesRead; i++ )
            intPtr[i] = intPtr[i] >> 8;
      }
      else {
Exemplo n.º 22
0
bool wfg_generateImage(char* audioFileName, char* pictureFileName, WFGO* options)
{	
	int width = options->width;
	int height = options->height;
	int seconds;
	long framesPerLine;

	// Initial audio part
	
	SF_INFO sfinfo;
	memset(&sfinfo, 0, sizeof(sfinfo));
	
	SNDFILE *sfile;
	if(audioFileName != NULL) {
		sfile =  sf_open(audioFileName, SFM_READ, &sfinfo);
	} else {
		sfile = sf_open_fd(STDIN_FILENO, SFM_READ, &sfinfo, 0);
	}
	
	if(sfile == NULL)
	{
		lastErrorMessage = "Could not open input file!";
		return false;
	}
	
	if(audioFileName == NULL) {
		seconds = options->trackLength;
		framesPerLine = ((long) seconds * sfinfo.samplerate) / width;
	} else {
		seconds = sfinfo.frames / sfinfo.samplerate;
		framesPerLine = (long) sfinfo.frames / width;
	}
	long samplesPerLine = framesPerLine * sfinfo.channels;
	
	// although one could think, that these values are flexible, the loops
	// below only work in these configurations (1/all or all/1)
	
	int channelsPerDrawing = 1;
	int drawnChannels = sfinfo.channels;
	
	if(options->mixChannels)
	{
		channelsPerDrawing = sfinfo.channels;
		drawnChannels = 1;
	}
		
	float * buffer = malloc(sizeof(float) * samplesPerLine);
	
	// malloc fail
	if(buffer == NULL)
	{
		lastErrorMessage = "Could not allocate memory!";
		sf_close(sfile);
		return false;
	}
	
	// Allocate Image
	gdImagePtr im = gdImageCreate(width,height);
	
	if(im == NULL)
	{
		lastErrorMessage = "Could not allocate image!";
		free(buffer);
		sf_close(sfile);
		return false;
	}
	
	// calculate how large one drawing should be
	
	int drawHeight = height;
	
	// leave space for the timeline
	if(options->drawTimeline)
		drawHeight -= 13;
	
	// subtract spacing
	drawHeight = drawHeight - ((drawnChannels - 1) * options->channelSpacing);
	
	// divide by drawnChannels
	drawHeight = drawHeight / drawnChannels;
	
	// background color
	int bgColor = gdImageColorAllocate(im,WFG_UNPACK_RGB(options->bgColor));
	
	if(options->transparentBg) {
		gdImageColorTransparent(im,bgColor);
	}
	
	int rmsColor =  gdImageColorAllocate(im, WFG_UNPACK_RGB(options->rmsColor));
	int peakColor = gdImageColorAllocate(im, WFG_UNPACK_RGB(options->peakColor));
	
	// too many nested loops ...
	for(int i = 0; i < width; i++)
	{
		if(sf_read_float(sfile, buffer, samplesPerLine) != samplesPerLine)
		{
			if(audioFileName == NULL) {
				memset(buffer, 0, samplesPerLine);
			} else {
				lastErrorMessage = "Could not read samples from audio file!";
				sf_close(sfile);
				free(buffer);
				gdImageDestroy(im);
				return false;
			}
		}
		
		int drawOffset = 0;

		for(int d = 0; d < drawnChannels; d++)
		{
			double val = 0.0;
			
			float peakP = 0.0;
			float peakM = 0.0;
			
			for(long e = 0; e < framesPerLine; e++)
			{
				for(int f = 0; f < channelsPerDrawing; f++)
				{
					float smpl = buffer[e * drawnChannels + d];
					val = val + (smpl*smpl);
					
					if(peakM > smpl)
						peakM = smpl;
					
					if(peakP < smpl)
						peakP = smpl;
				}
			}
			
			val = val / (float) (framesPerLine * channelsPerDrawing);
			val = sqrt(val);
			
			double ddrawHeight = drawHeight;
			
			int peakPP = drawHeight/2 -  round(peakP * (ddrawHeight/2.0));
			int peakMP = drawHeight/2 +  round(peakM * -1.0 * (ddrawHeight/2.0));
					
			// avoid rounding errors when peak is very small
			// if(peakP > 0.001 || peakM < -0.001) 
			gdImageLine(im, i,peakPP + drawOffset,i,peakMP + drawOffset, peakColor);
			
			int rmsSize;
			rmsSize = val * (double) (drawHeight/2);
			gdImageLine(im, i,drawHeight/2 - rmsSize + drawOffset,i,drawHeight/2 + rmsSize + drawOffset, rmsColor);
			
			drawOffset += drawHeight + options->channelSpacing;
		}
	}

	
	sf_close(sfile);
	free(buffer);
	
	if(options->drawTimeline)
		drawTimeline(im, options, seconds);
	
	// write out file
	FILE* file;
	if(pictureFileName) {
		file = fopen(pictureFileName,"wb");
	} else {
		file = stdout;
	}
	if(file == NULL)
	{
		lastErrorMessage = "Could not open output file!";
		gdImageDestroy(im);
	}
	
	gdImagePng(im,file);
	
	fclose(file);
	gdImageDestroy(im);
	
	return true;
}
Exemplo n.º 23
0
SNDFILE *
test_open_file_or_die (const char *filename, int mode, SF_INFO *sfinfo, int line_num)
{	static int count = 0 ;

	SNDFILE *file ;
	const char *modestr, *func_name ;
	int oflags = 0, omode = 0 ;

	/*
	** Need to test both sf_open() and sf_open_fd().
	** Do so alternately.
	*/

	switch (mode)
	{	case SFM_READ :
				modestr = "SFM_READ" ;
				oflags = O_RDONLY ;
				omode = 0 ;
				break ;

		case SFM_WRITE :
				modestr = "SFM_WRITE" ;
				oflags = O_WRONLY | O_CREAT | O_TRUNC ;
				omode = S_IRUSR | S_IWUSR | S_IRGRP ;
				break ;

		case SFM_RDWR :
				modestr = "SFM_RDWR" ;
				oflags = O_RDWR | O_CREAT ;
				omode = S_IRUSR | S_IWUSR | S_IRGRP ;
				break ;
		default :
				printf ("\n\nLine %d: Bad mode.\n", line_num) ;
				fflush (stdout) ;
				exit (1) ;
		} ;

#if (defined (__CYGWIN__) || defined (WIN32) || defined (_WIN32))
	/* Stupid fscking windows. */
	oflags |= O_BINARY ;
#endif

	if (((++count) & 1) == 1)
	{	int fd ;

		if (omode == 0)
			fd = open (filename, oflags) ;
		else
			fd = open (filename, oflags, omode) ;

		if (fd < 0)
		{	perror ("open") ;
			exit (1) ;
			} ;

		func_name = "sf_open_fd" ;
		file = sf_open_fd (fd, mode, sfinfo, SF_TRUE) ;
		}
	else
	{	func_name = "sf_open" ;
		file = sf_open (filename, mode, sfinfo) ;
		} ;

	if (file == NULL)
	{	printf ("\n\nLine %d: %s (%s) failed : %s\n\n", line_num, func_name, modestr, sf_strerror (NULL)) ;
		dump_log_buffer (file) ;
		exit (1) ;
		} ;

	return file ;
} /* test_open_file_or_die */
Exemplo n.º 24
0
void sfopenin(CSOUND *csound)           /* init for continuous soundin */
{
    OPARMS  *O = csound->oparms;
    char    *sfname, *fullName;
    SF_INFO sfinfo;
    int     fileType = (int) TYP_RAW;
    int     isfd = 0;   /* stdin */

    alloc_globals(csound);
    STA(inbufrem) = (uint32) 0;    /* start with empty buffer */
    sfname = O->infilename;
    if (UNLIKELY(sfname == NULL || sfname[0] == '\0'))
      csound->Die(csound, Str("error: no input file name"));

    if (strcmp(sfname, "stdin") == 0) {
      STA(pipdevin) = 1;
    }
#ifdef PIPES
    else if (sfname[0] == '|') {
      STA(pin) = _popen(sfname + 1, "r");
      isfd = fileno(STA(pin));
      STA(pipdevin) = 1;
    }
#endif
    else {
      csRtAudioParams   parm;
      /* check for real time audio input, and get device name/number */
      parm.devNum = check_rtaudio_name(sfname, &(parm.devName), 0);
      if (parm.devNum >= 0) {
        /* set device parameters */
        parm.bufSamp_SW   =
          (unsigned int) O->inbufsamps / (unsigned int) csound->inchnls;
        parm.bufSamp_HW   = O->oMaxLag;
        parm.nChannels    = csound->inchnls;
        parm.sampleFormat = O->informat;
        parm.sampleRate   = (float) csound->esr;
        /* open devaudio for input */
        if (UNLIKELY(csound->recopen_callback(csound, &parm) != 0))
          csoundDie(csound, Str("Failed to initialise real time audio input"));
        /*  & redirect audio gets  */
        csound->audrecv = csound->rtrecord_callback;
        STA(pipdevin) = 2;       /* no backward seeks !     */
        goto inset;             /* no header processing    */
      }
    }
    /* open file */
    memset(&sfinfo, 0, sizeof(SF_INFO));
    if (STA(pipdevin)) {
      STA(infile) = sf_open_fd(isfd, SFM_READ, &sfinfo, 0);
      if (UNLIKELY(STA(infile) == NULL)) {
        /* open failed: possibly raw file, but cannot seek back to try again */
        const char *sfError = Str(sf_strerror(NULL));
        csoundDie(csound, Str("isfinit: cannot open %s -- %s"), sfname, sfError);
      }
    }
    else {
      fullName = csoundFindInputFile(csound, sfname, "SFDIR;SSDIR");
      if (UNLIKELY(fullName == NULL))                     /* if not found */
        csoundDie(csound, Str("isfinit: cannot open %s"), sfname);
      STA(infile) = sf_open(fullName, SFM_READ, &sfinfo);
      if (STA(infile) == NULL) {
        /* open failed: maybe raw file ? */
        memset(&sfinfo, 0, sizeof(SF_INFO));
        sfinfo.samplerate = (int) MYFLT2LRND(csound->esr);
        sfinfo.channels = csound->nchnls;
        /* FIXME: assumes input sample format is same as output */
        sfinfo.format = TYPE2SF(TYP_RAW) | FORMAT2SF(O->outformat);
        STA(infile) = sf_open(fullName, SFM_READ, &sfinfo);  /* try again */
      }
      if (UNLIKELY(STA(infile) == NULL)) {
        const char *sfError = Str(sf_strerror(NULL));
        csoundDie(csound, Str("isfinit: cannot open %s -- %s"), fullName, sfError);
      }
      /* only notify the host if we opened a real file, not stdin or a pipe */
      csoundNotifyFileOpened(csound, fullName,
                              sftype2csfiletype(sfinfo.format), 0, 0);
      sfname = fullName;
    }
    /* chk the hdr codes  */
    if (sfinfo.samplerate != (int) MYFLT2LRND(csound->esr)) {
      csound->Warning(csound, Str("audio_in %s has sr = %d, orch sr = %d"),
                              sfname, (int) sfinfo.samplerate,
                              (int) MYFLT2LRND(csound->esr));
    }
    if (sfinfo.channels != csound->inchnls) {
      csound->Warning(csound, Str("audio_in %s has %d chnls, orch %d chnls_i"),
                              sfname, (int) sfinfo.channels, csound->inchnls);
    }
    /* Do we care about the format?  Can assume float?? */
    O->informat = SF2FORMAT(sfinfo.format);
    fileType = (int) SF2TYPE(sfinfo.format);
    csound->audrecv = readsf;           /* will use standard audio gets  */
    if ((O->informat == AE_FLOAT || O->informat == AE_DOUBLE) &&
        !(fileType == TYP_WAV || fileType == TYP_AIFF || fileType == TYP_W64)) {
      /* do not scale "raw" floating point files */
      csound->spinrecv = sndfilein_noscale;
    }

 inset:
    /* calc inbufsize reqd */
    STA(inbufsiz) = (unsigned) (O->inbufsamps * sizeof(MYFLT));
    STA(inbuf) = (MYFLT*) csound->Calloc(csound,
                                         STA(inbufsiz)); /* alloc inbuf space */
    if (STA(pipdevout) == 2)
      csound->Message(csound,
                      Str("reading %d sample blks of %lu-bit floats from %s\n"),
                      O->inbufsamps * O->sfsampsize,
                      (unsigned long) sizeof(MYFLT)*8, sfname);
    else {
      csound->Message(csound,
                      Str("reading %d-byte blks of %s from %s (%s)\n"),
                      O->inbufsamps * (int) sfsampsize(FORMAT2SF(O->informat)),
                      getstrformat(O->informat), sfname, type2string(fileType));
    }
    STA(isfopen) = 1;
}
Exemplo n.º 25
0
	void Music::play() {
#ifndef NO_SOUND
		music = nullptr;
		if(enabled) {
#if 0
			if(stream_intro.stream) {
				sf_close(stream_intro.stream);
				stream_intro.stream = nullptr;
			}
			if(stream_loop.stream) {
				sf_close(stream_loop.stream);
				stream_loop.stream = nullptr;
			}

			music_loop = true;
			music_end = false;

			//Open stream
			SF_INFO _info;
			//memset(&_info, 0, sizeof(_info));

			if(fileExists(intro)) {
				FILE* _fp = FOPEN(intro, "rb");
				if(_fp) {
					stream_intro.stream = sf_open_fd(fileno(_fp), SFM_READ, &_info, SF_TRUE);
					if(stream_intro.stream) {
						stream_intro.c_samples = _info.frames;
						stream_intro.sample_rate = _info.samplerate;
						stream_intro.channels = _info.channels;

						music_loop = false;
					}
				}
			}

			if(fileExists(loop)) {
				FILE* _fp = FOPEN(loop, "rb");
				if(_fp) {
					stream_loop.stream = sf_open_fd(fileno(_fp), SFM_READ, &_info, SF_TRUE);
					if(stream_loop.stream) {
						stream_loop.c_samples = _info.frames;
						stream_loop.sample_rate = _info.samplerate;
						stream_loop.channels = _info.channels;
					}
				}
			}
#endif

			music_is_loop = true;

			if(intro.exists()) {
				music_is_loop = false;
			}

			music = this;
			i_music_sample = 0.0;
		}
#else
		music = this;
#endif
	}
Exemplo n.º 26
0
static void
multi_file_test (const char *filename, int *formats, int format_count)
{	SNDFILE				*sndfile ;
	SF_INFO				sfinfo ;
	SF_EMBED_FILE_INFO	embed_info ;
	sf_count_t			filelen ;
	int					fd, k, file_count = 0 ;

	print_test_name ("multi_file_test", filename) ;

	unlink (filename) ;

	if ((fd = open (filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR)) < 0)
	{	printf ("\n\nLine %d: open failed : %s\n", __LINE__, strerror (errno)) ;
		exit (1) ;
		} ;

	k = write (fd, "1234", 4) ;

	for (k = 0 ; k < format_count ; k++)
		write_file_at_end (fd, formats [k], 2, k) ;

	filelen = file_length_fd (fd) ;

	embed_info.offset = 4 ;
	embed_info.length = 0 ;


	for (file_count = 1 ; embed_info.offset + embed_info.length < filelen ; file_count ++)
	{
		if (verbose)
		{	puts ("\n------------------------------------") ;
			printf ("This offset : %ld\n", SF_COUNT_TO_LONG (embed_info.offset + embed_info.length)) ;
			} ;

		if (lseek (fd, embed_info.offset + embed_info.length, SEEK_SET) < 0)
		{	printf ("\n\nLine %d: lseek failed : %s\n", __LINE__, strerror (errno)) ;
			exit (1) ;
			} ;

		memset (&sfinfo, 0, sizeof (sfinfo)) ;
		if ((sndfile = sf_open_fd (fd, SFM_READ, &sfinfo, SF_FALSE)) == NULL)
		{	printf ("\n\nLine %d: sf_open_fd failed\n", __LINE__) ;
			printf ("Embedded file number : %d   offset : %ld\n", file_count, SF_COUNT_TO_LONG (embed_info.offset)) ;
			puts (sf_strerror (sndfile)) ;
			dump_log_buffer (sndfile) ;
			exit (1) ;
			} ;

		sf_command (sndfile, SFC_GET_EMBED_FILE_INFO, &embed_info, sizeof (embed_info)) ;

		sf_close (sndfile) ;

		if (verbose)
			printf ("\nNext offset : %ld\nNext length : %ld\n", SF_COUNT_TO_LONG (embed_info.offset), SF_COUNT_TO_LONG (embed_info.length)) ;
		} ;

	file_count -- ;

	if (file_count != format_count)
	{	printf ("\n\nLine %d: file count (%d) not equal to %d.\n\n", __LINE__, file_count, format_count) ;
		printf ("Embedded file number : %d\n", file_count) ;
		exit (1) ;
		} ;

	close (fd) ;
	unlink (filename) ;
	printf ("ok\n") ;

	return ;
} /* multi_file_test */
Exemplo n.º 27
0
void sfopenout(CSOUND *csound)                  /* init for sound out       */
{                                               /* (not called if nosound)  */
    OPARMS  *O = csound->oparms;
    char    *s, *fName, *fullName;
    SF_INFO sfinfo;
    int     osfd = 1;   /* stdout */

    alloc_globals(csound);
    if (O->outfilename == NULL) {
      switch (O->filetyp) {
      case TYP_WAV:
      case TYP_W64:
      case TYP_WAVEX:
      case TYP_RF64:
        O->outfilename = "test.wav";
        break;
      case TYP_AIFF:
        O->outfilename = "test.aif";
        break;
      case TYP_AU:
        O->outfilename = "test.au";
        break;
      case TYP_PAF:
        O->outfilename = "test.paf";
        break;
      case TYP_SVX:
        O->outfilename = "test.svx";
        break;
      case TYP_NIST:
        O->outfilename = "test.sph";
        break;
      case TYP_VOC:
        O->outfilename = "test.voc";
        break;
      /* case TYP_IRCAM: */
      /*   O->outfilename = ""; */
      /*   break; */
      /* case TYP_MAT4: */
      /*   O->outfilename = ""; */
      /*   break;  */
      /* case TYP_MAT5: */
      /*   O->outfilename = ""; */
      /*   break;  */
      /* case TYP_PVF: */
      /*   O->outfilename = ""; */
      /*   break;   */
      case TYP_XI:
        O->outfilename = "test.xi";
        break;
      /* case TYP_HTK: */
      /*   O->outfilename = ""; */
      /*   break;   */
      /* case TYP_SDS: */
      /*   O->outfilename = "test.sds"; */
      /*   break;   */
      case TYP_AVR:
        O->outfilename = "test.avr";
        break;
      case TYP_SD2:
        O->outfilename = "test.sd2";
        break;
      case TYP_FLAC:
        O->outfilename = "test.flac";
        break;
      case TYP_CAF:
        O->outfilename = "test.caf";
        break;
      case TYP_OGG:
        O->outfilename = "test.ogg";
        break;
      /* case TYP_MPC2K: */
      /*   O->outfilename = ""; */
      /*   break; */
      default:
        O->outfilename = "test";
        break;
      }
    }
    STA(sfoutname) = fName = O->outfilename;

    if (strcmp(fName, "stdout") == 0) {
      STA(pipdevout) = 1;
    }
#ifdef PIPES
    else if (fName[0] == '|') {
      STA(pout) = _popen(fName+1, "w");
      osfd = fileno(STA(pout));
      STA(pipdevout) = 1;
      if (O->filetyp == TYP_AIFF || O->filetyp == TYP_WAV) {
        char fmt_name[6];
        if (O->sfsampsize == 8) {
          strcpy(fmt_name, "AU");
          O->filetyp = TYP_AU;
        }
        else {
          strcpy(fmt_name, "IRCAM");
          O->filetyp = TYP_IRCAM;
        }
        csound->Message(csound, Str("Output file type changed to %s "
                                    "for use in pipe\n"), fmt_name);
      }
    }
#endif
    else {
      csRtAudioParams   parm;
      /* check for real time audio output, and get device name/number */
      parm.devNum = check_rtaudio_name(fName, &(parm.devName), 1);
      if (parm.devNum >= 0) {
        /* set device parameters */
        parm.bufSamp_SW   = (unsigned int) O->outbufsamps / csound->nchnls;
        parm.bufSamp_HW   = O->oMaxLag;
        parm.nChannels    = csound->nchnls;
        parm.sampleFormat = O->outformat;
        parm.sampleRate   = (float) csound->esr;
        csound->spoutran  = spoutsf;
        /* open devaudio for output */
        if (UNLIKELY(csound->playopen_callback(csound, &parm) != 0))
          csoundDie(csound, Str("Failed to initialise real time audio output"));
        /*  & redirect audio puts  */
        csound->audtran = csound->rtplay_callback;
        STA(outbufrem)  = parm.bufSamp_SW * parm.nChannels;
        STA(pipdevout)  = 2;      /* no backward seeks !   */
        if (O->realtime == 1)     /* set realtime priority mode */
          csound->realtime_audio_flag = 1;
        goto outset;              /* no header needed      */
      }
      else if (strcmp(fName, "null") == 0) {
        STA(outfile) = NULL;
        if (csound->dither_output && csound->oparms->outformat!=AE_FLOAT &&
            csound->oparms->outformat!=AE_DOUBLE) {
          if (csound->oparms->outformat==AE_SHORT)
            if (csound->dither_output==1)
              csound->audtran = writesf_dither_16;
            else
              csound->audtran = writesf_dither_u16;
          else if (csound->oparms->outformat==AE_CHAR)
            if (csound->dither_output==1)
              csound->audtran = writesf_dither_8;
            else
              csound->audtran = writesf_dither_u8;
          else
            csound->audtran = writesf;
        }
        else
          csound->audtran = writesf;
        goto outset;
      }
    }
    /* set format parameters */
    memset(&sfinfo, 0, sizeof(SF_INFO));
    //sfinfo.frames     = 0;
    sfinfo.samplerate = (int) MYFLT2LRND(csound->esr);
    sfinfo.channels   = csound->nchnls;
    sfinfo.format     = TYPE2SF(O->filetyp) | FORMAT2SF(O->outformat);
    /* open file */
    if (STA(pipdevout)) {
      STA(outfile) = sf_open_fd(osfd, SFM_WRITE, &sfinfo, 0);
#ifdef PIPES
      if (STA(outfile) == NULL) {
        char fmt_name[6];
        if (O->sfsampsize == 8) {
          if (UNLIKELY(O->filetyp == TYP_AU))
            csoundDie(csound, Str("sfinit: cannot open fd %d\n%s"), osfd,
                      Str(sf_strerror(NULL)));
          strcpy(fmt_name, "AU");
          O->filetyp = TYP_AU;
        }
        else {
          if (UNLIKELY(O->filetyp == TYP_IRCAM))
            csoundDie(csound, Str("sfinit: cannot open fd %d\n%s"), osfd,
                      Str(sf_strerror(NULL)));
          strcpy(fmt_name, "IRCAM");
          O->filetyp = TYP_IRCAM;
        }
        csound->Message(csound, Str("Output file type changed to %s "
                                    "for use in pipe\n"), fmt_name);
        sfinfo.format = TYPE2SF(O->filetyp) | FORMAT2SF(O->outformat);
        STA(outfile) = sf_open_fd(osfd, SFM_WRITE, &sfinfo, 0);
      }
#endif
      if (UNLIKELY(STA(outfile) == NULL))
        csoundDie(csound, Str("sfinit: cannot open fd %d\n%s"), osfd,
                  Str(sf_strerror(NULL)));
      sf_command(STA(outfile), SFC_SET_VBR_ENCODING_QUALITY,
                 &O->quality, sizeof(double));
    }
    else {
      fullName = csoundFindOutputFile(csound, fName, "SFDIR");
      if (UNLIKELY(fullName == NULL))
        csoundDie(csound, Str("sfinit: cannot open %s"), fName);
      STA(sfoutname) = fullName;
      STA(outfile)   = sf_open(fullName, SFM_WRITE, &sfinfo);
      if (UNLIKELY(STA(outfile) == NULL))
        csoundDie(csound, Str("sfinit: cannot open %s\n%s"),
                  fullName, sf_strerror (NULL));
      sf_command(STA(outfile), SFC_SET_VBR_ENCODING_QUALITY,
                 &O->quality, sizeof(double));
      /* only notify the host if we opened a real file, not stdout or a pipe */
      csoundNotifyFileOpened(csound, fullName,
                              type2csfiletype(O->filetyp, O->outformat), 1, 0);
    }
    /* IV - Feb 22 2005: clip integer formats */
    if (O->outformat != AE_FLOAT && O->outformat != AE_DOUBLE)
      sf_command(STA(outfile), SFC_SET_CLIPPING, NULL, SF_TRUE);
    sf_command(STA(outfile), SFC_SET_ADD_PEAK_CHUNK,
               NULL, (csound->peakchunks ? SF_TRUE : SF_FALSE));
#ifdef SOME_FINE_DAY
    if (csound->dither_output) {        /* This may not be written yet!! */
      SF_DITHER_INFO  ditherInfo;
      memset(&ditherInfo, 0, sizeof(SF_DITHER_INFO));
      ditherInfo.type  = SFD_TRIANGULAR_PDF | SFD_DEFAULT_LEVEL;
      ditherInfo.level = 1.0;
      ditherInfo.name  = (char*) NULL;
      sf_command(STA(outfile), SFC_SET_DITHER_ON_WRITE,
                 &ditherInfo, sizeof(SF_DITHER_INFO));
    }
#endif
    if (!(O->outformat == AE_FLOAT || O->outformat == AE_DOUBLE) ||
        (O->filetyp == TYP_WAV || O->filetyp == TYP_AIFF ||
         O->filetyp == TYP_W64))
      csound->spoutran = spoutsf;       /* accumulate output */
    else
      csound->spoutran = spoutsf_noscale;
    if (csound->dither_output && csound->oparms->outformat!=AE_FLOAT &&
        csound->oparms->outformat!=AE_DOUBLE) {
      if (csound->oparms->outformat==AE_SHORT)
        csound->audtran = writesf_dither_16;
      else if (csound->oparms->outformat==AE_CHAR)
        csound->audtran = writesf_dither_8;
      else
        csound->audtran = writesf;
    }
    else
      csound->audtran = writesf;
    /* Write any tags. */
    if ((s = csound->SF_id_title) != NULL && *s != '\0')
      sf_set_string(STA(outfile), SF_STR_TITLE, s);
    if ((s = csound->SF_csd_licence) == NULL || *s == '\0')
      s = csound->SF_id_copyright;
    if (s != NULL && *s != '\0')
      sf_set_string(STA(outfile), SF_STR_COPYRIGHT, s);
    else if (csound->SF_id_scopyright>=0) {
      char buff[256];
      time_t tt = time(NULL);
      strftime(buff, 256, "Copyright %Y: ", gmtime(&tt));
      strncat(buff,copyrightcode(csound->SF_id_scopyright), 255);
      buff[255] = '\0';
      sf_set_string(STA(outfile), SF_STR_COPYRIGHT, buff);
    }
    if ((s = csound->SF_id_software) != NULL && *s != '\0')
      sf_set_string(STA(outfile), SF_STR_SOFTWARE, s);
    if ((s = csound->SF_id_artist) != NULL && *s != '\0')
      sf_set_string(STA(outfile), SF_STR_ARTIST, s);
    if ((s = csound->SF_id_comment) != NULL && *s != '\0')
      sf_set_string(STA(outfile), SF_STR_COMMENT, s);
    if ((s = csound->SF_id_date) != NULL && *s != '\0')
      sf_set_string(STA(outfile), SF_STR_DATE, s);
    /* file is now open */
    STA(osfopen) = 1;

 outset:
    O->sfsampsize = (int) sfsampsize(FORMAT2SF(O->outformat));
    /* calc outbuf size & alloc bufspace */
    STA(outbufsiz) = O->outbufsamps * sizeof(MYFLT);
    STA(outbufp)   = STA(outbuf) = csound->Malloc(csound, STA(outbufsiz));
    if (STA(pipdevout) == 2)
      csound->Message(csound,
                      Str("writing %d sample blks of %lu-bit floats to %s\n"),
                      O->outbufsamps, (unsigned long) sizeof(MYFLT)*8,
                      STA(sfoutname));
    else {
     csound->Message(csound, Str("writing %d-byte blks of %s to %s"),
                    O->outbufsamps * O->sfsampsize,
                    getstrformat(O->outformat), STA(sfoutname));

    if (O->sfheader == 0)
      csound->Message(csound, Str(" (raw)\n"));
    else
      csound->Message(csound, " (%s)\n", type2string(O->filetyp));
    }
    STA(osfopen)   = 1;
    STA(outbufrem) = O->outbufsamps;
}
Exemplo n.º 28
0
int playfile(FILE *fp)
{
    int frames_read;
    int frames_written;
    int total_read = 0;
    int total_written = 0;
    int count;
    int toread;
    int *buffer;
    long filestart;

    SNDFILE     *sndfile;
    SF_INFO     sf_info;

    SNDFILE     *outfile;
    SF_INFO     outfile_info;

    filestart = ftell(fp);

    memset(&sf_info, 0, sizeof(SF_INFO));
    memset(&outfile_info, 0, sizeof(SF_INFO));

    sndfile = sf_open_fd(fileno(fp), SFM_READ, &sf_info, 0);

    outfile_info.format = SF_FORMAT_AIFF | SF_FORMAT_PCM_S8;
    outfile_info.channels = sf_info.channels;
    outfile_info.samplerate = sf_info.samplerate;

    outfile = sf_open("sampleout.aiff", SFM_WRITE, &outfile_info);

    buffer = malloc(BUFFSIZE * sf_info.channels * sizeof(int));
    frames_read = 0;
    toread = sf_info.frames * sf_info.channels;

    printf("Total frames:     %d\n\n", toread);

    while (toread > 0) {
	if (toread < BUFFSIZE * sf_info.channels)
	    count = toread;
	else
	    count = BUFFSIZE * sf_info.channels;

	printf("Frames attempted: %d\n", count);

        frames_read = sf_read_int(sndfile, buffer, count);
	frames_written = sf_write_int(outfile, buffer, count);
	toread = toread - frames_read;
        total_written += frames_written;
        total_read += frames_read;
	printf("frames read:      %d\n", frames_read);
	printf("frames remaining: %d\n\n", toread);
    }

    fseek(fp, filestart, SEEK_SET);
    sf_close(sndfile);
    free(buffer);

    printf("Read:    %d\n", total_read);
    printf("Written: %d\n", total_written);
    printf("Finished\n");

    return 0;
}
Exemplo n.º 29
0
/// Reads the specified data from the aliased file, using libsndfile,
/// and converts it to the given sample format.
/// Copied from PCMAliasBlockFIle but wxLog calls taken out for thread safety
///
/// @param data   The buffer to read the sample data into.
/// @param format The format to convert the data into
/// @param start  The offset within the block to begin reading
/// @param len    The number of samples to read
int ODPCMAliasBlockFile::ReadData(samplePtr data, sampleFormat format,
                                sampleCount start, sampleCount len)
{

   mReadDataMutex.Lock();

   SF_INFO info;

   if(!mAliasedFileName.IsOk()){ // intentionally silenced 
      memset(data,0,SAMPLE_SIZE(format)*len);
      mReadDataMutex.Unlock();

         return len;
   }

   memset(&info, 0, sizeof(info));

   wxString aliasPath = mAliasedFileName.GetFullPath();
   //there are thread-unsafe crashes here - not sure why.  sf_open may be called on the same file
   //from different threads, but this seems okay, unless it is implemented strangely..  
   static ODLock sfMutex;

   wxFile f;   // will be closed when it goes out of scope
   SNDFILE *sf = NULL;

   if (f.Open(aliasPath)) {
      // Even though there is an sf_open() that takes a filename, use the one that
      // takes a file descriptor since wxWidgets can open a file with a Unicode name and
      // libsndfile can't (under Windows).
      ODManager::LockLibSndFileMutex();
      sf = sf_open_fd(f.fd(), SFM_READ, &info, FALSE);
      ODManager::UnlockLibSndFileMutex();
   }
   
   if (!sf){
      
      memset(data,0,SAMPLE_SIZE(format)*len);

      mSilentAliasLog=TRUE;

      mReadDataMutex.Unlock();
      return len;
   }

   mSilentAliasLog=FALSE;

   ODManager::LockLibSndFileMutex();
   sf_seek(sf, mAliasStart + start, SEEK_SET);
   ODManager::UnlockLibSndFileMutex();

   samplePtr buffer = NewSamples(len * info.channels, floatSample);

   int framesRead = 0;

   if (format == int16Sample &&
       !sf_subtype_more_than_16_bits(info.format)) {
      // Special case: if the file is in 16-bit (or less) format,
      // and the calling method wants 16-bit data, go ahead and
      // read 16-bit data directly.  This is a pretty common
      // case, as most audio files are 16-bit.
      ODManager::LockLibSndFileMutex();
      framesRead = sf_readf_short(sf, (short *)buffer, len);
      ODManager::UnlockLibSndFileMutex();

      for (int i = 0; i < framesRead; i++)
         ((short *)data)[i] =
            ((short *)buffer)[(info.channels * i) + mAliasChannel];
   }
   else {
      // Otherwise, let libsndfile handle the conversion and
      // scaling, and pass us normalized data as floats.  We can
      // then convert to whatever format we want.
      ODManager::LockLibSndFileMutex();
      framesRead = sf_readf_float(sf, (float *)buffer, len);
      ODManager::UnlockLibSndFileMutex();
      float *bufferPtr = &((float *)buffer)[mAliasChannel];
      CopySamples((samplePtr)bufferPtr, floatSample,
                  (samplePtr)data, format,
                  framesRead, true, info.channels);
   }

   DeleteSamples(buffer);

   ODManager::LockLibSndFileMutex();
   sf_close(sf);
   ODManager::UnlockLibSndFileMutex();
   
   mReadDataMutex.Unlock();
   return framesRead;
}
Exemplo n.º 30
0
int pa_sound_file_load(
        pa_mempool *pool,
        const char *fname,
        pa_sample_spec *ss,
        pa_channel_map *map,
        pa_memchunk *chunk,
        pa_proplist *p) {

    SNDFILE *sf = NULL;
    SF_INFO sfi;
    int ret = -1;
    size_t l;
    sf_count_t (*readf_function)(SNDFILE *sndfile, void *ptr, sf_count_t frames) = NULL;
    void *ptr = NULL;
    int fd;

    pa_assert(fname);
    pa_assert(ss);
    pa_assert(chunk);

    pa_memchunk_reset(chunk);

    if ((fd = pa_open_cloexec(fname, O_RDONLY, 0)) < 0) {
        pa_log("Failed to open file %s: %s", fname, pa_cstrerror(errno));
        goto finish;
    }

#ifdef HAVE_POSIX_FADVISE
    if (posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL) < 0) {
        pa_log_warn("POSIX_FADV_SEQUENTIAL failed: %s", pa_cstrerror(errno));
        goto finish;
    } else
        pa_log_debug("POSIX_FADV_SEQUENTIAL succeeded.");
#endif

    pa_zero(sfi);
    if (!(sf = sf_open_fd(fd, SFM_READ, &sfi, 1))) {
        pa_log("Failed to open file %s", fname);
        goto finish;
    }

    fd = -1;

    if (pa_sndfile_read_sample_spec(sf, ss) < 0) {
        pa_log("Failed to determine file sample format.");
        goto finish;
    }

    if ((map && pa_sndfile_read_channel_map(sf, map) < 0)) {
        if (ss->channels > 2)
            pa_log("Failed to determine file channel map, synthesizing one.");
        pa_channel_map_init_extend(map, ss->channels, PA_CHANNEL_MAP_DEFAULT);
    }

    if (p)
        pa_sndfile_init_proplist(sf, p);

    if ((l = pa_frame_size(ss) * (size_t) sfi.frames) > PA_SCACHE_ENTRY_SIZE_MAX) {
        pa_log("File too large");
        goto finish;
    }

    chunk->memblock = pa_memblock_new(pool, l);
    chunk->index = 0;
    chunk->length = l;

    readf_function = pa_sndfile_readf_function(ss);

    ptr = pa_memblock_acquire(chunk->memblock);

    if ((readf_function && readf_function(sf, ptr, sfi.frames) != sfi.frames) ||
        (!readf_function && sf_read_raw(sf, ptr, (sf_count_t) l) != (sf_count_t) l)) {
        pa_log("Premature file end");
        goto finish;
    }

    ret = 0;

finish:

    if (sf)
        sf_close(sf);

    if (ptr)
        pa_memblock_release(chunk->memblock);

    if (ret != 0 && chunk->memblock)
        pa_memblock_unref(chunk->memblock);

    if (fd >= 0)
        pa_close(fd);

    return ret;
}