19 Commits

Author SHA1 Message Date
Ariel Elkin
889328c3c1 Update README-iOS.md
fix markdown syntax
2017-05-18 16:53:46 -03:00
Gary Scavone
62416d7e3f Fix to FileWvIn / FileLoop for file open issue and normalization. 2017-05-04 16:32:53 -04:00
Gary Scavone
9627701d04 Added optional argument to FileWvIn and FileLoop to distinguish int-to-float scaling from data normalization. The default values should produce the same behaviour as before. 2017-05-03 16:15:42 -04:00
Gary Scavone
9966f06757 FMVoices bug fix to avoid currentVowel > 31. 2017-05-03 15:20:19 -04:00
Gary Scavone
56bcdc32ed Fix to zero new delay memory in setMaximumDelay() function. 2017-02-24 08:36:02 -05:00
Gary Scavone
2ddc79e3bd Bug fix for MAT-files in FileWrite.cpp 2017-02-18 10:08:57 -05:00
Gary Scavone
96b1a72186 Bug fix in MidiFileIn.cpp for timing with time-code formats. 2016-11-02 18:03:25 -04:00
Gary Scavone
2a6ada02a7 Updates to demo project scripts to specify the path to the binary file 2016-09-21 15:10:56 -04:00
garyscavone
488301223a Merge pull request #64 from rhenninger/patch-1
#63: add separate index for tokens in parseString
2016-09-14 19:50:57 -04:00
garyscavone
08f71c8fa9 Merge pull request #66 from rhenninger/patch-2
redirect non-conforming writes to cerr to oStream_
2016-09-14 19:49:34 -04:00
rhenninger
e03aa486dd redirect non-conforming writes to cerr to oStream_
One error message was going to cerr instead of oStream_ in resonate.cpp
2016-09-11 13:51:10 -04:00
rhenninger
5dd605ecfd redirect non-conforming writes to cerr to oStream_
One error message in mandolin.cpp was going to cerr instead of oStream_
2016-09-11 13:47:25 -04:00
rhenninger
77a5cfa4aa redirect non-conforming writes to cerr to oStream_
Most error messages go to oStream_.  Two in guitar.cpp don't conform.
2016-09-11 13:38:57 -04:00
Gary Scavone
77bdb45575 Bug fix in duplex.cpp 2016-09-06 11:27:36 -04:00
rhenninger
ff52b9f0b0 Need to cover zero token case (Shakers)
Previous fix to#63 didn't cover case where there are no tokens left because skini messages provides all values.  For example, changing a shaker instrument has no further tokens, but rather pulls two constants directly from skini_msgs[].  Changed test ca line161 to bail out when more tokens are expected and none are left: when data type is SK_INT, SK_DBL or SK_STR (all less than 0)
2016-08-15 09:16:50 -04:00
rhenninger
fe0f5d7f96 Update Skini.cpp 2016-08-06 08:40:07 -04:00
rhenninger
e1aa259517 #63: add separate index for tokens in parseString
Added a separate index for accessing tokens leaving the original index for values to work as it always does.  Code now correctly parses SKINI text for midi extension commands as well as basic commands.
2016-08-06 08:11:35 -04:00
garyscavone
95fcd14213 Merge pull request #56 from ryandesign/master
Fix build on case-sensitive OS X
2016-02-26 07:54:41 -05:00
Ryan Schmidt
a5bef56e76 Fix build on case-sensitive OS X
Fix capitalization of CoreMIDI framework to fix build on Macs with
case-sensitive filesystems.
2016-02-25 22:23:37 -06:00
25 changed files with 106 additions and 75 deletions

View File

@@ -167,7 +167,7 @@ if test $realtime = yes; then
api="$api -D__MACOSX_CORE__"
AC_MSG_RESULT(using CoreAudio)
AC_CHECK_HEADER(CoreAudio/CoreAudio.h, [], [AC_MSG_ERROR(CoreAudio header files not found!)] )
LIBS="$LIBS -framework CoreAudio -framework CoreFoundation -framework CoreMidi" ], )
LIBS="$LIBS -framework CoreAudio -framework CoreFoundation -framework CoreMIDI" ], )
# If no audio api flags specified, use CoreAudio
if [test "$api" == ""; ] then
@@ -176,7 +176,7 @@ if test $realtime = yes; then
AC_CHECK_HEADER(CoreAudio/CoreAudio.h,
[],
[AC_MSG_ERROR(CoreAudio header files not found!)] )
AC_SUBST( LIBS, ["-framework CoreAudio -framework CoreFoundation -framework CoreMidi"] )
AC_SUBST( LIBS, ["-framework CoreAudio -framework CoreFoundation -framework CoreMIDI"] )
fi
AC_CHECK_LIB(pthread, pthread_create, , AC_MSG_ERROR(RtAudio requires the pthread library!))

View File

@@ -56,7 +56,7 @@ STK compiles with realtime support on the following flavors of the Unix operatin
<TD>Macintosh OS X</TD>
<TD>CoreAudio</TD>
<TD>__MACOSX_CORE__</TD>
<TD><TT>pthread, CoreAudio, CoreMidi, CoreFoundation</TT></TD>
<TD><TT>pthread, CoreAudio, CoreMIDI, CoreFoundation</TT></TD>
</TR>
</TABLE>
</CENTER>

View File

@@ -1,14 +1,14 @@
This file contains instructions for integrating the STK in Xcode projects and solutions to common integration issues.
##Setup
## Setup
###If you have [Cocoapods](http://cocoapods.org/)
### If you have [Cocoapods](http://cocoapods.org/)
1. Add `pod 'STK', '~> 4.5'` to your Podfile.
1. Run `pod install`
###If you don't have Cocoapods
### If you don't have Cocoapods
1. Clone or [download][download_link] the STK into your project's directory.
@@ -21,7 +21,7 @@ This file contains instructions for integrating the STK in Xcode projects and so
![][header_search_paths_screenshot]
##Usage
## Usage
1. Import the STK classes in the source files you require.
* E.g. `#import "SineWave.h"`
@@ -32,9 +32,9 @@ This file contains instructions for integrating the STK in Xcode projects and so
You can also look at the [iOS Demo project](..projects/demo/iOS%20Demo) for a sample usage.
##Troubleshooting
## Troubleshooting
###'FileName.h' file not found
### 'FileName.h' file not found
If you get this error when `#import`ing an STK header, you have added the wrong header search path for the STK in your project's settings (see Step 4 in Setup)
@@ -49,19 +49,19 @@ If this problem doesn't go away:
If that doesn't solve it:
Install Cocoapods and use it to install the STK. It takes one minute and will make your life easier. Visit the [Cocoapods website](http://cocoapods.org/) for installation instructions.
###FileRead::open: could not open or find file (../../rawwaves/filename.raw)!
### FileRead::open: could not open or find file (../../rawwaves/filename.raw)!
If you use a class that makes use of raw waves (such as `Mandolin`, `Wurley`, or `Rhodey`) you need to make sure that the STK's raw wave files are copied into your bundle and that the STK knows where they are. You'll know you need to if you get this runtime error:
`FileRead::open: could not open or find file (../../rawwaves/filename.raw)!`
####If you're using Cocoapods
#### If you're using Cocoapods
Add this code before using a class that needs the raw waves:
```objective-c
stk::Stk::setRawwavePath([[[NSBundle mainBundle] pathForResource:@"rawwaves" ofType:@"bundle"] UTF8String]);
```
####If you're not using Cocoapods
#### If you're not using Cocoapods
1. Open your project's settings, open the *Build Phases* tab.
1. In the *Copy Bundle Resources*, drag and drop **rawwaves.bundle** (it's located in **STK.xcodeproj**'s **Helpers** folder).
@@ -73,7 +73,7 @@ stk::Stk::setRawwavePath([[rawwaveBundle resourcePath] UTF8String]);
```
###rawwaves.bundle: No such file or directory
### rawwaves.bundle: No such file or directory
This means that **rawwaves.bundle** hasn't been copied to the build folder, so you'll need to do it manually:
@@ -83,7 +83,7 @@ Select the rawwaves scheme:
Build it (⌘+B) then build your project's main scheme.
###Apple Mach-O Linker Error
### Apple Mach-O Linker Error
This means that **STKLib.a** isn't being linked to your binary. Follow step 2 above in [Setup](#setup).

View File

@@ -31,7 +31,8 @@ class FileLoop : protected FileWvIn
//! Class constructor that opens a specified file.
FileLoop( std::string fileName, bool raw = false, bool doNormalize = true,
unsigned long chunkThreshold = 1000000, unsigned long chunkSize = 1024 );
unsigned long chunkThreshold = 1000000, unsigned long chunkSize = 1024,
bool doInt2FloatScaling = true );
//! Class destructor.
~FileLoop( void );
@@ -40,13 +41,14 @@ class FileLoop : protected FileWvIn
/*!
Data from a previously opened file will be overwritten by this
function. An StkError will be thrown if the file is not found,
its format is unknown, or a read error occurs. If the file data
is to be loaded incrementally from disk and normalization is
specified, a scaling will be applied with respect to fixed-point
limits. If the data format is floating-point, no scaling is
performed.
its format is unknown, or a read error occurs. If the file length
is less than the chunkThreshold limit and \e doNormalize is true,
the file data will be normalized with respect to the maximum absolute
value of the data. If the \e doInt2FloatScaling flag is true and the
input data is fixed-point, a scaling will be applied with respect to
the fixed-point limits.
*/
void openFile( std::string fileName, bool raw = false, bool doNormalize = true );
void openFile( std::string fileName, bool raw = false, bool doNormalize = true, bool doInt2FloatScaling = true );
//! Close a file if one is open.
void closeFile( void ) { FileWvIn::closeFile(); };

View File

@@ -29,6 +29,16 @@ namespace stk {
chunkThreshold (in sample frames) will be read incrementally in
chunks of \e chunkSize each (also in sample frames).
For file data read completely into local memory, the \e doNormalize
flag can be used to normalize all values with respect to the maximum
absolute value of the data.
If the file data format is fixed point, the flag \e doInt2FloatScaling
can be used to control whether the values are scaled with respect to
the corresponding fixed-point maximum. For example, if reading 16-bit
signed integers, the input values will be scaled by 1 / 32768.0. This
scaling will not happen for floating-point file data formats.
When the file end is reached, subsequent calls to the tick()
functions return zeros and isFinished() returns \e true.
@@ -51,7 +61,8 @@ public:
unknown, or a read error occurs.
*/
FileWvIn( std::string fileName, bool raw = false, bool doNormalize = true,
unsigned long chunkThreshold = 1000000, unsigned long chunkSize = 1024 );
unsigned long chunkThreshold = 1000000, unsigned long chunkSize = 1024,
bool doInt2FloatScaling = true );
//! Class destructor.
~FileWvIn( void );
@@ -60,13 +71,14 @@ public:
/*!
Data from a previously opened file will be overwritten by this
function. An StkError will be thrown if the file is not found,
its format is unknown, or a read error occurs. If the file data
is to be loaded incrementally from disk and normalization is
specified, a scaling will be applied with respect to fixed-point
limits. If the data format is floating-point, no scaling is
performed.
its format is unknown, or a read error occurs. If the file length
is less than the chunkThreshold limit and \e doNormalize is true,
the file data will be normalized with respect to the maximum absolute
value of the data. If the \e doInt2FloatScaling flag is true and the
input data is fixed-point, a scaling will be applied with respect to
the fixed-point limits.
*/
virtual void openFile( std::string fileName, bool raw = false, bool doNormalize = true );
virtual void openFile( std::string fileName, bool raw = false, bool doNormalize = true, bool doInt2FloatScaling = true );
//! Close a file if one is open.
virtual void closeFile( void );
@@ -158,7 +170,7 @@ public:
performed if _STK_DEBUG_ is defined during compilation, in which
case an out-of-range value will trigger an StkError exception.
*/
virtual StkFrames& tick( StkFrames& frames,unsigned int channel = 0 );
virtual StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
protected:
@@ -167,7 +179,7 @@ protected:
FileRead file_;
bool finished_;
bool interpolate_;
bool normalizing_;
bool int2floatscaling_;
bool chunking_;
StkFloat time_;
StkFloat rate_;

View File

@@ -1 +1 @@
wish < tcl/Banded.tcl | stk-demo BandedWG -or -ip
wish < tcl/Banded.tcl | ./stk-demo BandedWG -or -ip

View File

@@ -1 +1 @@
wish < tcl/Drums.tcl | stk-demo Drummer -or -ip
wish < tcl/Drums.tcl | ./stk-demo Drummer -or -ip

View File

@@ -1 +1 @@
wish < tcl/Modal.tcl | stk-demo ModalBar -or -ip
wish < tcl/Modal.tcl | ./stk-demo ModalBar -or -ip

View File

@@ -1 +1 @@
wish < tcl/Physical.tcl | stk-demo Clarinet -or -ip
wish < tcl/Physical.tcl | ./stk-demo Clarinet -or -ip

View File

@@ -1 +1 @@
wish < tcl/Shakers.tcl | stk-demo Shakers -or -ip
wish < tcl/Shakers.tcl | ./stk-demo Shakers -or -ip

View File

@@ -1 +1 @@
wish < tcl/Demo.tcl | stk-demo Clarinet -or -ip
wish < tcl/Demo.tcl | ./stk-demo Clarinet -or -ip

View File

@@ -1 +1 @@
wish < tcl/Voice.tcl | stk-demo FMVoices -or -ip
wish < tcl/Voice.tcl | ./stk-demo FMVoices -or -ip

View File

@@ -104,6 +104,7 @@ int main(int argc, char *argv[])
RtAudio::StreamOptions options;
//options.flags |= RTAUDIO_NONINTERLEAVED;
bufferBytes = bufferFrames * channels * sizeof( MY_TYPE );
try {
adac.openStream( &oParams, &iParams, FORMAT, fs, &bufferFrames, &inout, (void *)&bufferBytes, &options );
}
@@ -112,8 +113,6 @@ int main(int argc, char *argv[])
exit( 1 );
}
bufferBytes = bufferFrames * channels * sizeof( MY_TYPE );
// Test RtAudio functionality for reporting latency.
std::cout << "\nStream latency = " << adac.getStreamLatency() << " frames" << std::endl;

View File

@@ -23,7 +23,7 @@
using namespace stk;
// Eewww ... global variables! :-)
bool done;
bool done = false;
StkFrames frames;
static void finish(int ignore){ done = true; }
@@ -45,9 +45,10 @@ int tick( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
double streamTime, RtAudioStreamStatus status, void *userData )
{
FileWvIn *input = (FileWvIn *) userData;
register StkFloat *samples = (StkFloat *) outputBuffer;
StkFloat *samples = (StkFloat *) outputBuffer;
input->tick( frames );
for ( unsigned int i=0; i<frames.size(); i++ ) {
*samples++ = frames[i];
if ( input->channelsOut() == 1 ) *samples++ = frames[i]; // play mono files in stereo

View File

@@ -42,7 +42,7 @@ Delay :: ~Delay()
void Delay :: setMaximumDelay( unsigned long delay )
{
if ( delay < inputs_.size() ) return;
inputs_.resize( delay + 1 );
inputs_.resize( delay + 1, 1, 0.0 );
}
void Delay :: setDelay( unsigned long delay )

View File

@@ -98,10 +98,11 @@ void FMVoices :: setFrequency( StkFloat frequency )
i = currentVowel_ - 64;
temp2 = 1.1;
}
else if (currentVowel_ <= 128) {
else if (currentVowel_ < 128) {
i = currentVowel_ - 96;
temp2 = 1.2;
}
else return;
baseFrequency_ = frequency;
temp = (temp2 * Phonemes::formantFrequency(i, 0) / baseFrequency_) + 0.5;
@@ -140,7 +141,7 @@ void FMVoices :: controlChange( int number, StkFloat value )
if (number == __SK_Breath_) // 2
gains_[3] = fmGains_[(int) ( normalizedValue * 99.9 )];
else if (number == __SK_FootControl_) { // 4
currentVowel_ = (int) (normalizedValue * 128.0);
currentVowel_ = (int) (normalizedValue * 127.0);
this->setFrequency(baseFrequency_);
}
else if (number == __SK_ModFrequency_) // 11

View File

@@ -28,10 +28,11 @@ FileLoop :: FileLoop( unsigned long chunkThreshold, unsigned long chunkSize )
}
FileLoop :: FileLoop( std::string fileName, bool raw, bool doNormalize,
unsigned long chunkThreshold, unsigned long chunkSize )
unsigned long chunkThreshold, unsigned long chunkSize,
bool doInt2FloatScaling )
: FileWvIn( chunkThreshold, chunkSize ), phaseOffset_(0.0)
{
this->openFile( fileName, raw, doNormalize );
this->openFile( fileName, raw, doNormalize, doInt2FloatScaling );
Stk::addSampleRateAlert( this );
}
@@ -40,7 +41,7 @@ FileLoop :: ~FileLoop( void )
Stk::removeSampleRateAlert( this );
}
void FileLoop :: openFile( std::string fileName, bool raw, bool doNormalize )
void FileLoop :: openFile( std::string fileName, bool raw, bool doNormalize, bool doInt2FloatScaling )
{
// Call close() in case another file is already open.
this->closeFile();
@@ -53,16 +54,19 @@ void FileLoop :: openFile( std::string fileName, bool raw, bool doNormalize )
chunking_ = true;
chunkPointer_ = 0;
data_.resize( chunkSize_ + 1, file_.channels() );
if ( doNormalize ) normalizing_ = true;
else normalizing_ = false;
}
else {
chunking_ = false;
data_.resize( file_.fileSize() + 1, file_.channels() );
}
if ( doInt2FloatScaling )
int2floatscaling_ = true;
else
int2floatscaling_ = false;
// Load all or part of the data.
file_.read( data_, 0, doNormalize );
file_.read( data_, 0, int2floatscaling_ );
if ( chunking_ ) { // If chunking, save the first sample frame for later.
firstFrame_.resize( 1, data_.channels() );
@@ -134,6 +138,8 @@ StkFloat FileLoop :: tick( unsigned int channel )
}
#endif
if ( finished_ ) return 0.0;
// Check limits of time address ... if necessary, recalculate modulo
// fileSize.
while ( time_ < 0.0 )
@@ -171,7 +177,7 @@ StkFloat FileLoop :: tick( unsigned int channel )
}
// Load more data.
file_.read( data_, chunkPointer_, normalizing_ );
file_.read( data_, chunkPointer_, int2floatscaling_ );
}
// Adjust index for the current buffer.
@@ -195,7 +201,7 @@ StkFloat FileLoop :: tick( unsigned int channel )
StkFrames& FileLoop :: tick( StkFrames& frames, unsigned int channel)
{
if ( !file_.isOpen() ) {
if ( finished_ ) {
#if defined(_STK_DEBUG_)
oStream_ << "FileLoop::tick(): no file data is loaded!";
handleError( StkError::DEBUG_PRINT );

View File

@@ -688,8 +688,9 @@ void FileWrite :: closeMatFile( void )
SINT32 headsize, temp;
fseek(fd_, 196, SEEK_SET); // jump to header size
if (fread(&headsize, 4, 1, fd_) < 4) {
if (fread(&headsize, 4, 1, fd_) != 1) {
oStream_ << "FileWrite: could not read MAT-file header size.";
handleError( StkError::WARNING );
goto close_file;
}
@@ -699,7 +700,7 @@ void FileWrite :: closeMatFile( void )
// Write file size (minus some header info)
fwrite(&headsize, 4, 1, fd_);
fseek(fd_, temp+196, SEEK_SET); // jumpt to data size (in bytes)
fseek(fd_, temp+196, SEEK_SET); // jump to data size (in bytes)
temp = (SINT32) (frameCounter_ * 8 * channels_);
fwrite(&temp, 4, 1, fd_);

View File

@@ -44,11 +44,12 @@ FileWvIn :: FileWvIn( unsigned long chunkThreshold, unsigned long chunkSize )
}
FileWvIn :: FileWvIn( std::string fileName, bool raw, bool doNormalize,
unsigned long chunkThreshold, unsigned long chunkSize )
unsigned long chunkThreshold, unsigned long chunkSize,
bool doInt2FloatScaling )
: finished_(true), interpolate_(false), time_(0.0), rate_(0.0),
chunkThreshold_(chunkThreshold), chunkSize_(chunkSize)
{
openFile( fileName, raw, doNormalize );
openFile( fileName, raw, doNormalize, doInt2FloatScaling );
Stk::addSampleRateAlert( this );
}
@@ -71,7 +72,7 @@ void FileWvIn :: closeFile( void )
lastFrame_.resize( 0, 0 );
}
void FileWvIn :: openFile( std::string fileName, bool raw, bool doNormalize )
void FileWvIn :: openFile( std::string fileName, bool raw, bool doNormalize, bool doInt2FloatScaling )
{
// Call close() in case another file is already open.
this->closeFile();
@@ -84,16 +85,19 @@ void FileWvIn :: openFile( std::string fileName, bool raw, bool doNormalize )
chunking_ = true;
chunkPointer_ = 0;
data_.resize( chunkSize_, file_.channels() );
if ( doNormalize ) normalizing_ = true;
else normalizing_ = false;
}
else {
chunking_ = false;
data_.resize( (size_t) file_.fileSize(), file_.channels() );
}
if ( doInt2FloatScaling )
int2floatscaling_ = true;
else
int2floatscaling_ = false;
// Load all or part of the data.
file_.read( data_, 0, doNormalize );
file_.read( data_, 0, int2floatscaling_ );
// Resize our lastFrame container.
lastFrame_.resize( 1, file_.channels() );
@@ -204,7 +208,7 @@ StkFloat FileWvIn :: tick( unsigned int channel )
}
// Load more data.
file_.read( data_, chunkPointer_, normalizing_ );
file_.read( data_, chunkPointer_, int2floatscaling_ );
}
// Adjust index for the current buffer.
@@ -228,9 +232,9 @@ StkFloat FileWvIn :: tick( unsigned int channel )
StkFrames& FileWvIn :: tick( StkFrames& frames, unsigned int channel)
{
if ( !file_.isOpen() ) {
if ( finished_ ) {
#if defined(_STK_DEBUG_)
oStream_ << "FileWvIn::tick(): no file data is loaded!";
oStream_ << "FileWvIn::tick(): end of file or no open file!";
handleError( StkError::DEBUG_PRINT );
#endif
return frames;
@@ -258,7 +262,6 @@ StkFrames& FileWvIn :: tick( StkFrames& frames, unsigned int channel)
}
}
return frames;
}
} // stk namespace

View File

@@ -117,7 +117,7 @@ void Guitar :: setBodyFile( std::string bodyfile )
void Guitar :: setPluckPosition( StkFloat position, int string )
{
if ( position < 0.0 || position > 1.0 ) {
std::cerr << "Guitar::setPluckPosition: position parameter out of range!";
oStream_ << "Guitar::setPluckPosition: position parameter out of range!";
handleError( StkError::WARNING ); return;
}
@@ -136,7 +136,7 @@ void Guitar :: setPluckPosition( StkFloat position, int string )
void Guitar :: setLoopGain( StkFloat gain, int string )
{
if ( gain < 0.0 || gain > 1.0 ) {
std::cerr << "Guitar::setLoopGain: gain parameter out of range!";
oStream_ << "Guitar::setLoopGain: gain parameter out of range!";
handleError( StkError::WARNING ); return;
}

View File

@@ -75,7 +75,7 @@ void Mandolin :: clear( void )
void Mandolin :: setPluckPosition( StkFloat position )
{
if ( position < 0.0 || position > 1.0 ) {
std::cerr << "Mandolin::setPluckPosition: position parameter out of range!";
oStream_ << "Mandolin::setPluckPosition: position parameter out of range!";
handleError( StkError::WARNING ); return;
}

View File

@@ -79,7 +79,8 @@ MidiFileIn :: MidiFileIn( std::string fileName )
usingTimeCode_ = false;
if ( *data & 0x8000 ) {
// Determine ticks per second from time-code formats.
tickrate = (double) -(*data & 0x7F00);
signed char tmp = -(*data & 0xFF00)>>8;
tickrate = (double) tmp;
// If frames per second value is 29, it really should be 29.97.
if ( tickrate == 29.0 ) tickrate = 29.97;
tickrate *= (*data & 0x00FF);

View File

@@ -56,7 +56,7 @@ void Resonate :: setResonance( StkFloat frequency, StkFloat radius )
}
if ( radius < 0.0 || radius >= 1.0 ) {
std::cerr << "Resonate::setResonance: radius parameter is out of range!";
oStream_ << "Resonate::setResonance: radius parameter is out of range!";
handleError( StkError::WARNING ); return;
}

View File

@@ -1010,7 +1010,7 @@ void MidiOutCore :: openVirtualPort( std::string portName )
void MidiOutCore :: sendMessage( std::vector<unsigned char> *message )
{
// We use the MIDISendSysex() function to asynchronously send sysex
// messages. Otherwise, we use a single CoreMidi MIDIPacket.
// messages. Otherwise, we use a single CoreMIDI MIDIPacket.
unsigned int nBytes = message->size();
if ( nBytes == 0 ) {
errorString_ = "MidiOutCore::sendMessage: no data in message argument!";

View File

@@ -153,10 +153,13 @@ long Skini :: parseString( std::string& line, Message& message )
// Parse the remaining fields (maximum of 2 more).
int iValue = 0;
unsigned int iToken = iValue + 3; //rgh: MIDI extension argument counts are different from regular MIDI
long dataType = skini_msgs[iSkini].data2;
while ( dataType != NOPE ) {
if ( tokens.size() <= (unsigned int) (iValue+3) ) {
// if ( tokens.size() <= (unsigned int) (iValue+3) ) { //rgh: test iToken rather than always testing iValue+3
// if (tokens.size() <= iToken) { //rgh: iToken only tests it more tokens are to be consumed (SK_INT, SK_DBL, SK_STR)
if ((tokens.size() <= iToken) && (dataType < 0)) { //Don't fail if remaining iValues come from skini_msgs[] rather than tokens[].
oStream_ << "Skini::parseString: inconsistency between type table and parsed line:\n " << line;
handleError( StkError::WARNING );
return message.type = 0;
@@ -165,23 +168,25 @@ long Skini :: parseString( std::string& line, Message& message )
switch ( dataType ) {
case SK_INT:
message.intValues[iValue] = atoi( tokens[iValue+3].c_str() );
message.intValues[iValue] = atoi( tokens[iToken].c_str() ); //rgh: use new index
message.floatValues[iValue] = (StkFloat) message.intValues[iValue];
++iToken; //rgh: increment token index and value index (below)
break;
case SK_DBL:
message.floatValues[iValue] = atof( tokens[iValue+3].c_str() );
message.floatValues[iValue] = atof( tokens[iToken].c_str() ); //rgh: use new index
message.intValues[iValue] = (long) message.floatValues[iValue];
++iToken; //rgh: increment token index and value index (below)
break;
case SK_STR: // Must be the last field.
message.remainder = tokens[iValue+3];
message.remainder = tokens[iToken]; //rgh: use new index
return message.type;
default: // MIDI extension message
message.intValues[iValue] = dataType;
message.floatValues[iValue] = (StkFloat) message.intValues[iValue];
iValue--;
//iValue--; //rgh: iValue must increment even when iToken does not; resetting iValue only works sometimes
}
if ( ++iValue == 1 )