[Stk] RtAudio - Read entire file to memory
TJF
tjfoerster at web.de
Thu Apr 15 05:14:23 PDT 2010
Hi,
it nearly works now. I can hear the music from the output buffer, but it
sounds like in a "bad dream". Any idea in which area I could look for
the next step?
typedef signed short MY_TYPE;
#define FORMAT RTAUDIO_SINT16
#define SCALE 32767.0
..............
struct OutputData {
FILE *fd;
unsigned int size;
size_t result;
size_t count;
void *buffer;
unsigned int position;
unsigned int channels;
};
Regards
Thomas
TJF schrieb:
> I have tried several things meanwhile. I.e.:
>
> samples in buffer[numbers of] = N Frames * X channels (---> count )
> bufferSize[bytes] = N Frames * X channels * bytes(bit depth ---> size
> of MY_TYPE)
>
> but it doesn't work. Any idea what is still wrong?
>
> Thanks.
> Thomas
>
> _______________________________________________________
>
> int output( void *outputBuffer, void *inputBuffer, unsigned int
> nBufferFrames,
> double streamTime, RtAudioStreamStatus status, void *data )
>
> {
> unsigned int i;
> OutputData *oData = (OutputData*) data;
> oData->count = oData->result/sizeof(MY_TYPE); // number of samples in
> buffer (result = size of buffer)
> 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;
> }
> return (oData->position >= oData->count);
> }
>
>
>
> Stephen Sinclair schrieb:
>> 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
>>>
>>>
>>>
>>>
>>
>> _______________________________________________
>> Stk mailing list
>> Stk at ccrma.stanford.edu
>> http://ccrma-mail.stanford.edu/mailman/listinfo/stk
>>
>
More information about the Stk
mailing list