[Stk] RtAudio - Read entire file to memory

Stephen Sinclair sinclair at music.mcgill.ca
Tue Mar 30 05:49:13 PDT 2010


On Tue, Mar 30, 2010 at 12:57 PM, TJF <tjfoerster at web.de> wrote:
> I did this (s.b.), compiling with warning "conversion from 'double' in
> 'MY_TYPE'" for this line:
>
>  *out++ = 0.0;
>
> I changed "int i;" to "unsigned int i;"

Sorry about that, yes the type is integer so it should have been "*out++ = 0;"

> The compiled code has the same behaviour (doesn't output) ...

In any case, I can't debug all your code for you, but do you
understand what it is doing?

Steve


>
> _________________________________________________
>
> /******************************************/
> /*
>  playraw.cpp
>  by Gary P. Scavone, 2007
>
>  Play a specified raw file.  It is necessary
>  that the file be of the same data format as
>  defined below.
> */
> /******************************************/
>
> #include "RtAudio.h"
> #include <iostream>
> #include <cstdlib>
> #include <cstring>
> #include <stdio.h>
>
> /*
> typedef char  MY_TYPE;
> #define FORMAT RTAUDIO_SINT8
> #define SCALE  127.0
> */
>
> typedef signed short  MY_TYPE;
> #define FORMAT RTAUDIO_SINT16
> #define SCALE  32767.0
>
> /*
> typedef signed long  MY_TYPE;
> #define FORMAT RTAUDIO_SINT24
> #define SCALE  8388607.0
>
> typedef signed long  MY_TYPE;
> #define FORMAT RTAUDIO_SINT32
> #define SCALE  2147483647.0
>
> typedef float  MY_TYPE;
> #define FORMAT RTAUDIO_FLOAT32
> #define SCALE  1.0;
>
> typedef double  MY_TYPE;
> #define FORMAT RTAUDIO_FLOAT64
> #define SCALE  1.0;
> */
>
> // Platform-dependent sleep routines.
> #if defined( __WINDOWS_ASIO__ ) || defined( __WINDOWS_DS__ )
>  #include <windows.h>
>  #define SLEEP( milliseconds ) Sleep( (DWORD) milliseconds )
> #else // Unix variants
>  #include <unistd.h>
>  #define SLEEP( milliseconds ) usleep( (unsigned long) (milliseconds *
> 1000.0) )
> #endif
>
> void usage( void ) {
>  // Error function in case of incorrect command-line
>  // argument specifications
>  std::cout << "\nuseage: playraw N fs file <device> <channelOffset>\n";
>  std::cout << "    where N = number of channels,\n";
>  std::cout << "    fs = the sample rate, \n";
>  std::cout << "    file = the raw file to play,\n";
>  std::cout << "    device = optional device to use (default = 0),\n";
>  std::cout << "    and channelOffset = an optional channel offset on
> the device (default = 0).\n\n";
>  exit( 0 );
> }
>
> struct OutputData {
>  FILE *fd;
>  void *buffer;
>  unsigned int position;
>  unsigned int count;
>  unsigned int channels;
> };
>
> // Interleaved buffers
> int output( void *outputBuffer, void *inputBuffer, unsigned int
> nBufferFrames,
>            double streamTime, RtAudioStreamStatus status, void *data )
> {
>  unsigned int i;
>  OutputData *oData = (OutputData*) data;
>  MY_TYPE *out = (MY_TYPE *)outputBuffer;
>  MY_TYPE *buf = &((MY_TYPE *)oData->buffer)[oData->position];
>  for (i=0; i < nBufferFrames; i++) {
>    if (oData->position < oData->count) {
>        *out++ = *buf++;
>        ++oData->position;
>    } else
>        *out++ = 0.0;
>  }
>  return (oData->position >= oData->count);
> }
>
> /*
> {
>  OutputData *oData = (OutputData*) data;
>
>  // In general, it's not a good idea to do file input in the audio
>  // callback function but I'm doing it here because I don't know the
>  // length of the file we are reading.
>  unsigned int data.count = fread( outputBuffer, oData->channels *
> sizeof( MY_TYPE ), nBufferFrames, oData->fd);
>  if ( count < nBufferFrames ) {
>    unsigned int bytes = (nBufferFrames - data.count) * oData->channels
> * sizeof( MY_TYPE );
>    unsigned int startByte = data.count * oData->channels * sizeof(
> MY_TYPE );
>    memset( (char *)(outputBuffer)+startByte, 0, bytes );
>    return 1;
>  }
>
>  return 0;
> }
> */
>
> int main( int argc, char *argv[] )
> {
>  unsigned int channels, fs, bufferFrames, device = 0, offset = 0;
>  char *file;
>
>  // minimal command-line checking
>  if ( argc < 4 || argc > 6 ) usage();
>
>  RtAudio dac;
>  if ( dac.getDeviceCount() < 1 ) {
>    std::cout << "\nNo audio devices found!\n";
>    exit( 0 );
>  }
>
>  channels = (unsigned int) atoi( argv[1]) ;
>  fs = (unsigned int) atoi( argv[2] );
>  file = argv[3];
>  if ( argc > 4 )
>    device = (unsigned int) atoi( argv[4] );
>  if ( argc > 5 )
>    offset = (unsigned int) atoi( argv[5] );
>
> // -------- original section playraw.cpp - beginning
> ------------------------------------
> /*
>  OutputData data;
>  data.fd = fopen( file, "rb" );
>  if ( !data.fd ) {
>   std::cout << "Unable to find or open file!\n";
>   exit( 1 );
>  }
> */
> // -------- original - end
> --------------------------------------------------------------
>
> // -------- replaced code - beginning
> ---------------------------------------------------
>
>   OutputData data;
>   int Size;
>   size_t result;
>   data.fd = fopen ( file , "rb" );
>   std::cout << "\ndata.fd1 " << data.fd << std::endl;
>   if (data.fd==NULL) {
>       std::cout << "Unable to find or open file!\n";
>       exit (1);
>   }
>   fseek (data.fd , 0 , SEEK_END);
>   Size = ftell (data.fd);
>   data.buffer = calloc (Size,1);
>   std::cout << "\nbuffer:  " << data.buffer << std::endl;
>   if (data.buffer == NULL) {
>       std::cout << "Memory error!\n";
>       exit (2);
>   }
>   rewind (data.fd);
>   result = fread (data.buffer,1,Size,data.fd);
>   std::cout << "\ndata.fd2 " << data.fd << std::endl;
>   if (result != Size) {
>       std::cout << "Reading error!\n";
>       exit (3);
>   }
>
> // -------- replaced code - end
> ---------------------------------------------------------
>
>
>  // Set our stream parameters for output only.
>  bufferFrames = 512;
>  RtAudio::StreamParameters oParams;
>  oParams.deviceId = device;
>  oParams.nChannels = channels;
>  oParams.firstChannel = offset;
>
>  data.channels = channels;
>  try {
>    dac.openStream( &oParams, NULL, FORMAT, fs, &bufferFrames, &output,
> (void *)&data );
>    dac.startStream();
>  }
>  catch ( RtError& e ) {
>    std::cout << '\n' << e.getMessage() << '\n' << std::endl;
>    goto cleanup;
>  }
>
>  std::cout << "\nPlaying raw file " << file << " (buffer frames = " <<
> bufferFrames << ")." << std::endl;
>  while ( 1 ) {
>    SLEEP( 100 ); // wake every 100 ms to check if we're done
>    if ( dac.isStreamRunning() == false ) break;
>  }
>
>  cleanup:
>  fclose( data.fd );
>  dac.closeStream();
>
>  return 0;
> }
>
>
>
> Stephen Sinclair schrieb:
>> On Tue, Mar 30, 2010 at 12:10 PM, TJF <tjfoerster at web.de> wrote:
>>
>>> Yes Steve, you understand correctly.
>>>
>>> Now I've added "buffer" to the OutputData struct (s.b.). But how can I
>>> "copy it into
>>> outputBuffer"?
>>>
>>
>> Note, you'll have to also put the file size "count" into OutputData,
>> and a position tracker, I'll call it "position", which should be
>> initialized to zero.
>>
>> Then something like, (not tested):
>>
>> ------------------------------------
>> // Interleaved buffers
>> int output( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
>>             double streamTime, RtAudioStreamStatus status, void *data )
>> {
>>   int i;
>>   OutputData *oData = (OutputData*) data;
>>   MY_TYPE *out = (MY_TYPE *)outputBuffer;
>>   MY_TYPE *buf = &((MY_TYPE *)oData->buffer)[oData->position];
>>   for (i=0; i < nBufferFrames; i++) {
>>     if (oData->position < oData->count) {
>>         *out++ = *buf++;
>>         ++oData->position;
>>     } else
>>         *out++ = 0.0;
>>   }
>>   return (oData->position >= oData->count);
>> }
>> ------------------------------------
>>
>>
>> Steve
>>
>> _______________________________________________
>> Stk mailing list
>> Stk at ccrma.stanford.edu
>> http://ccrma-mail.stanford.edu/mailman/listinfo/stk
>>
>>
>
> _______________________________________________
> Stk mailing list
> Stk at ccrma.stanford.edu
> http://ccrma-mail.stanford.edu/mailman/listinfo/stk
>
>
>



More information about the Stk mailing list