Commit 2c8df6e1 authored by Dan Stowell's avatar Dan Stowell

Imported Upstream version 3.5.4~repack

parent 01827563
......@@ -122,12 +122,14 @@ if(WIN32)
add_definitions(-DWIN32_LEAN_AND_MEAN)
if(MSVC)
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_RELEASE} /MTd")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_DEBUG} /MT")
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
endif()
# correctly link the static Boost Thread library:
add_definitions(-DBOOST_THREAD_USE_LIB)
#avoid unnecesary autolink
add_definitions(-DBOOST_DATE_TIME_NO_LIB)
endif()
......
......@@ -5,7 +5,22 @@ related:: Overviews/GUI-Classes, Guides/GUI-Introduction, Classes/ViewRedirect
description::
The GUI class provides a means of writing cross platform gui code. GUI provides Factory abstraction for all gui related core classes. Each gui kit is described by a gui scheme which maps class names to actual classes. These schemes are in turn used by link::Classes/ViewRedirect:: to provide a simple cross-platform gui syntax. It also provide utilities for switching kits and other cross platform tasks. You can get your available schemes (depending on what you installed) with:
SuperCollider currently supports three operating system platforms: Macintosh OSX, UNIX (Linux and FreeBSD) and Windows (with some limitations).
Graphical User Interface (GUI) code, for the most part, does not need to worry about which platform is executing the code because of the strong::view redirect:: system. At any time, one and only one strong::GUI kit:: is active. This determines which GUI classes will be used for rendering. These classes, the active views, have prefixes for the GUI kit that created the view object: SCWindow vs. JSCWindow vs. QWindow.
table::
## strong::GUI kit:: || strong::Code to activate:: || strong::Supported platform(s):: || strong::Framework:: || strong::Prefix::
## Cocoa || code::GUI.cocoa:: || Mac OSX only || Cocoa || SC-
## SwingOSC || code::GUI.swing:: || All || Java + Swing || JSC-
## Qt || code::GUI.qt:: || All || Qt || Q-
::
In general, users should not concern themselves with the prefixes. Instead, work with the emphasis::redirect:: classes, which have no prefix: Window, Button, Slider, etc. The redirect class will ask the currently-selected kit which emphasis::implementation class:: should be used.
The GUI kit (CocoaGUI, QtGUI, SwingGUI) maps the generic view names to the implementing classes: code::Window --> SCWindow, QWindow or JSCWindow::. These schemes are in turn used by link::Classes/ViewRedirect:: to provide a simple cross-platform gui syntax. The GUI class provides utilities for switching kits and other cross platform tasks.
You can get your available schemes (depending on what you installed) with:
code::
GUI.schemes;
::
......@@ -14,16 +29,18 @@ For a complete list of gui classes and redirects, see link::Overviews/GUI-Classe
subsection:: Switching and Referring to GUI Kits
As of this writing, two GUI kits are available through the GUI class: link::Classes/CocoaGUI:: (Mac OS X native) and link::Classes/SwingGUI:: (Java). Note that link::Classes/SwingOSC:: is not part of every SuperCollider distribution, so you may have to install it separately.
As of this writing, three GUI kits are available through the GUI class: link::Classes/QtGUI:: (Qt framework), link::Classes/CocoaGUI:: (Mac OS X native) and link::Classes/SwingGUI:: (Java). Note that link::Classes/SwingOSC:: is not part of every SuperCollider distribution, so you may have to install it separately.
You can switch the GUI kit by calling one of the following class methods:
code::
GUI.qt; // use Qt in subsequent GUI creation procedures
GUI.cocoa; // use cocoa in subsequent GUI creation procedures
GUI.swing; // use swing in subsequent GUI creation procedures
// NOTE: If you do not have SwingOSC installed, you get
// a warning only, and do not switch; so you cannot
// accidentally disable your (mac) gui system.
// accidentally disable your gui system.
::
These methods return the new GUI kit implementation. The current implementation can be queried by calling
code::
GUI.current; // returns the current GUI kit implementation
......
......@@ -59,7 +59,7 @@ code::
(
o = OSCFunc({ |msg|
"rms: %, peak: %".format(msg[3], msg[4]).postln
"peak: %, rms: %".format(msg[3], msg[4]).postln
}, '/replyAddress');
)
o.free;
......
......@@ -7,7 +7,7 @@ String represents an array of characters.
Strings can be written literally using double quotes:
code::
"my string".class.postln;
"my string".class
::
A sequence of string literals will be concatenated together:
code::
......@@ -39,17 +39,16 @@ private::prUnixCmd, prFormat, prCat, prBounds, hash, species, getSCDir, prDrawIn
subsection:: Accessing characters
method::@
method::at
method::@, at
Strings respond to .at in a manner similar to other indexed collections. Each element is a link::Classes/Char::.
code::
"ABCDEFG".at(2).postln;
"ABCDEFG".at(2)
::
method::ascii
Returns an Array of asci numbers of the Strings's characters.
code::
"wertvoll".ascii;
"wertvoll".ascii
::
subsection:: Comparing strings
......@@ -59,26 +58,59 @@ Returns a -1, 0, or 1 depending on whether the receiver should be sorted before
method::<
Returns a link::Classes/Boolean:: whether the receiver should be sorted before the argument.
code::
"same" < "samf"
::
method::>
Returns a link::Classes/Boolean:: whether the receiver should be sorted after the argument.
code::
"same" > "samf"
::
method::<=
Returns a link::Classes/Boolean:: whether the receiver should be sorted before the argument, including the same string.
code::
"same" <= "same"
"same" <= "samf"
::
method::>=
Returns a link::Classes/Boolean:: whether the receiver should be sorted after the argument, including the same string.
code::
"same" >= "same"
"same" >= "samf"
::
method::==
Returns a link::Classes/Boolean:: whether the two Strings are equal.
note::
This method is case insensitive! Use code::a.compare(b)==0:: if you need case sensitivity.
This method is (now) case sensitive!
::
code::
"same" == "same"
"same" == "Same"; // false
::
method::!=
Returns a link::Classes/Boolean:: whether the two Strings are not equal.
code::
"same" != "same"; // false
"same" != "Same";
::
subsection:: Posting strings
method::post
Prints the string to the current post window.
code::
"One".post; "Two".post;"";
::
method::postln
Prints the string and a carriage return to the current post window.
code::
"One".postln; "Two".postln;"";
::
method::postc, postcln
As link::#-post:: and link::#-postln::, but formatted as a comment.
......@@ -102,12 +134,21 @@ List[1, 2, ["comment", [3, 2]], { 1.0.rand }].postcs;
method::error
Prepends an error banner and posts the string.
code::
"Do not press this button again".error;
::
method::warn
Prepends a warning banner and posts the string.
code::
"Do not press this button again".warn;
::
method::inform
Posts the string.
code::
"Do not press this button again".inform;
::
subsection:: Interpreting strings as code
......@@ -187,9 +228,15 @@ subsection:: Concatenate strings
method::++
Return a concatenation of the two strings.
code::
"hello" ++ "word"
::
method::+
Return a concatenation of the two strings with a space between them.
code::
"hello" + "word"
::
method::+/+
Path concatenation operator - useful for avoiding doubling-up slashes unnecessarily.
......@@ -249,6 +296,8 @@ code::
"aaaabaaa".findAllRegexp("a+");
::
method::findAllRegexp
Like link::#-findAll::, but use regular expressions.
subsection:: Searching strings
......@@ -306,33 +355,18 @@ A link::Classes/Boolean::
subsection:: Manipulating strings
method::escapeChar
Add the escape character (\) before any character of your choice.
method::rotate
Rotate the string by n steps.
code::
// escape spaces:
"This will become a Unix friendly string".escapeChar($ ).postln;
"hello word".rotate(1)
::
method::shellQuote
Return a new string suitable for use as a filename in a shell command, by enclosing it in single quotes ( teletype::':: ).
If the string contains any single quotes they will be escaped.
discussion::
You should use this method on a path before embedding it in a string executed by link::#-unixCmd:: or link::#-systemCmd::.
method::scramble
Randomize the order of characters in the string.
code::
unixCmd("ls"+Platform.userExtensionDir.shellQuote)
::
note::
This works well with shells such as strong::bash::, other shells might need different quotation/escaping.
"hello word".scramble
::
method::quote
Return this string enclosed in double-quote ( teletype::":: ) characters.
method::tr
Transliteration. Replace all instances of strong::from:: with strong::to::.
code::
":-(:-(:-(".tr($(, $)); //turn the frowns upside down
::
method::replace
Like link::#-tr::, but with strings as arguments.
......@@ -348,6 +382,38 @@ format("this % a %. pi = %, list = %\n", "is", "test", pi.round(1e-4), (1..4))
this is a test. pi = 3.1416, list = [ 1, 2, 3, 4 ]
::
method::escapeChar
Add the escape character (\) before any character of your choice.
code::
// escape spaces:
"This will become a Unix friendly string".escapeChar($ ).postln;
::
method::quote
Return this string enclosed in double-quote ( teletype::":: ) characters.
code::
"tell your" + "friends".quote + "not to tread onto the lawn"
::
method::zeroPad
Return this string enclosed in space characters.
code::
"spaces".zeroPad.postcs;
::
method::underlined
Return this string followed by dashes in the next line ( teletype::-:: ).
code::
"underlined".underlined;
"underlined".underlined($~);
::
method::tr
Transliteration. Replace all instances of strong::from:: with strong::to::.
code::
":-(:-(:-(".tr($(, $)); //turn the frowns upside down
::
method::padLeft
method::padRight
......@@ -356,12 +422,23 @@ argument:: size
Number of characters to fill
argument:: string
Padding string
code::
"this sentence has thirty-nine letters".padRight(39, "-+");
"this sentence has thirty-nine letters".padLeft(30, "-+");
"this sentence has thirty-nine letters".padRight(13, "-+"); // nothing to pad.
::
method::toUpper
Return this string with uppercase letters.
code::
"Please, don't be impolite".toUpper;
::
method::toLower
Return this string with lowercase letters.
code::
"SINOSC".toLower;
::
method::stripRTF
Returns a new String with all RTF formatting removed.
......@@ -482,6 +559,12 @@ code::
"USER".getenv;
::
method::unsetenv
Set the environment variable to nil.
method::mkdir
Make a directory from the given path location.
method::pathMatch
Returns an link::Classes/Array:: containing all paths matching this String. Wildcards apply, non-recursive.
code::
......@@ -534,6 +617,19 @@ subsection::Pathname Support
Also see link::#-+/+:: for path concatenation.
method::shellQuote
Return a new string suitable for use as a filename in a shell command, by enclosing it in single quotes ( teletype::':: ).
If the string contains any single quotes they will be escaped.
discussion::
You should use this method on a path before embedding it in a string executed by link::#-unixCmd:: or link::#-systemCmd::.
code::
unixCmd("ls " + Platform.userExtensionDir.shellQuote)
::
note::
This works well with shells such as strong::bash::, other shells might need different quotation/escaping.
Apart from usage in the construction of shell commands, strong::escaping is not needed:: for paths passed to methods like pathMatch(path) or File.open(path).
::
method::absolutePath
method::asAbsolutePath
Return this path as an absolute path by prefixing it with link::Classes/File#*getcwd:: if necessary.
......
......@@ -4,30 +4,52 @@ categories:: GUI
SECTION:: Platform indepedent GUI code
SECTION:: First problem: Platform independence
SuperCollider provides for writing graphical user interface code that may be executed by different GUI kits implementing the same functionality. A user may not worry about the different implementations and under most circumstances generic GUI code will have the same effect in any of them. Nontheless, there may appear slight differences between them, therefore it's worth mentioning them here.
strong::Why do you need to know about this?::
subsection:: Different GUI kits
numberedlist::
## You'll create a Window.new and wonder why you got back a SCWindow or QWindow.
## You might use Mac-only GUI objects and wonder why your friend on Windows can't run your code.
## On Mac, you might run some examples that are specific to Q- objects and wonder why they don't work right away.
::
strong::Short answer::
Various GUI kits are managed by the link::Classes/GUI:: class. See it's documentation for details of how to switch the active GUI kit.
Make sure you select the right strong::GUI kit::.
At the moment of this writing, there exist three GUI kits:
When SuperCollider starts, one of the available kits becomes the default.
table::
## strong::Platform:: || strong::Default kit::
## Mac OSX || Cocoa -- code::GUI.cocoa::
## Linux/FreeBSD || Qt -- code::GUI.qt::
## Windows || Qt -- code::GUI.qt::
::
## strong::Name:: || strong::Implementation:: || strong::Availability::
## strong::Cocoa:: || Mac OS Cocoa toolkit || Only on Mac OS, within the SuperCollider application
## strong::SwingOSC:: || Java || Cross-platform, running as a separate program and commuincating with SuperCollider via OSC.
## strong::Qt:: || Qt framework || Cross-platform.
For most cases, the Qt GUI kit is sufficient. Cocoa is retained as the default in Mac OSX for historical reasons. (This may change in a future release.)
warning:: Some GUI examples are Qt-specific. They are labeled as such in the documentation. Strong::These examples will not work in OSX unless you manually switch to the Qt kit:: by running the following code:
code::GUI.qt;::
::
subsection:: Generic GUI code
See the link::Classes/GUI:: help file for more background on the GUI kits.
subsection:: Use "GUI redirect" classes whenever possible
There is a set of classes available for writing generic GUI code. When they are instantiated an instance of the kit-specific equivalent class is returned instead. The equivalent classes of all the GUI kits implement a large set of common methods which can therefore be used in generic code, and are documented as belonging to the generic class.
It is strongly recommended to use generic view class names: Window, Button, Slider, etc. Code written using the generic names can run in other GUI kits.
The kit-specific classes typically have the same name as their generic equivalents, but prefixed with an identifier of the implementation: "SC" for Cocoa, "JSC" for SwingOSC and "Q" for Qt.
code::
// DO write
w = Window.new.front;
// DO NOT write
w = SCWindow.new.front;
::
In the second example, the use of the Cocoa-specific window class ensures that the code will not run in Linux or Windows without modification. This is usually not a good idea.
For a list of all the generic GUI classes and their kit-specific equivalents see link::Overviews/GUI-Classes::.
......@@ -36,7 +58,6 @@ In the rest of this document we will refer to GUI classes by their generic name,
SECTION:: Basic elements: Windows, views and containers
The most fundamental element of the GUI is the strong::Window::. It occupies a rectangular space on screen within which other GUI elements are displayed. It usually has a bar that displays the window's title and allows for moving it, resizing it and closing it with the controls it displays or through mouse and keyboard interaction. Some of these aspects may be controlled within SuperCollider GUI code, though it is largely platform-dependent how precisely interaction with a window happens and is visually indicated.
......
......@@ -226,7 +226,7 @@ void QcMultiSlider::mouseMoveEvent( QMouseEvent *e )
return;
}
double xStep;
qreal xStep;
QRect r( valueRect( c - startIndex, xStep ) );
......@@ -336,10 +336,10 @@ void QcMultiSlider::paintEvent( QPaintEvent *e )
}
int count = _values.count() - startIndex;
double spacing, width, yscale;
qreal spacing, width, yscale;
spacing = elastic ? (double) bounds.width() / count : thumbSize.width() + gap;
width = elastic ? qMin( spacing, (double) thumbSize.width() ) : thumbSize.width();
spacing = elastic ? (qreal) bounds.width() / count : thumbSize.width() + gap;
width = elastic ? qMin( spacing, (qreal) thumbSize.width() ) : thumbSize.width();
yscale = bounds.height();
if( !isFilled ) yscale -= thumbSize.height();
......
......@@ -109,7 +109,7 @@ class QcMultiSlider : public QWidget, QcHelper, QtCollider::Style::Client
void setStartIndex( int i ) { startIndex = qBound(0, i, _values.count()-1); update(); }
QRect contentsRect();
QRect valueRect( int count, double & spacing );
QRect valueRect( int count, qreal & spacing );
inline float valueFromPos( float pos, float range );
inline void setValue( int index, double value );
double rounded ( double value );
......
......@@ -47,7 +47,15 @@ Mix {
{ \control } { result }
{ \scalar } { DC.kr(result) }
{ Error("Unsupported rate % for Mix.kr".format(result.rate)).throw };
}
}
*arFill { |n, function|
^this.ar(Array.fill(n, function))
}
*krFill { |n, function|
^this.kr(Array.fill(n, function))
}
}
......
......@@ -65,7 +65,7 @@
prepareForProxySynthDef { arg proxy;
proxy.initBus(\control, 1);
^{DC.multiNewList([proxy.rate] ++ this) };
^{DC.multiNewList([proxy.rate] ++ this) };
}
}
......@@ -82,7 +82,7 @@
+RawArray {
prepareForProxySynthDef { arg proxy;
proxy.initBus(\control, this.size);
^{DC.multiNewList([proxy.rate] ++ this) };
^{DC.multiNewList([proxy.rate] ++ this) };
}
}
......
......@@ -29,6 +29,9 @@ int scdoclex_destroy(void);
char * scdoc_current_file = NULL;
const char * NODE_TEXT = "TEXT";
const char * NODE_NL = "NL";
static int doc_node_dump_level_done[32] = {0,};
// merge a+b and free b
......@@ -119,20 +122,20 @@ void doc_node_free_tree(DocNode *n) {
void doc_node_fixup_tree(DocNode *n) {
int i;
if(n->id != "TEXT" && n->text) {
if(n->id != NODE_TEXT && n->text) {
n->text = striptrailingws(n->text);
}
if(n->n_childs) {
DocNode *last = n->children[n->n_childs-1];
if(last->id=="NL") {
if(last->id==NODE_NL) {
free(last); // NL has no text or children
n->n_childs--;
}
last = NULL;
for(i = 0; i < n->n_childs; i++) {
DocNode *child = n->children[i];
if((child->id=="TEXT" || child->id=="NL") && last && last->id=="TEXT") {
if(child->id=="NL") {
if((child->id==NODE_TEXT || child->id==NODE_NL) && last && last->id==NODE_TEXT) {
if(child->id==NODE_NL) {
last->text = (char*)realloc(last->text,strlen(last->text)+2);
strcat(last->text," ");
} else {
......
......@@ -5,6 +5,9 @@
#define SCDOC_PARSE_PARTIAL 1
#define SCDOC_PARSE_METADATA 2
extern const char * NODE_TEXT;
extern const char * NODE_NL;
typedef struct DocNode {
const char *id;
char *text;
......
......@@ -2690,7 +2690,7 @@ yyreduce:
/* Line 1455 of yacc.c */
#line 292 "SCDoc.y"
{ (yyval.doc_node) = doc_node_make("TEXT",(yyvsp[(1) - (1)].str),NULL); ;}
{ (yyval.doc_node) = doc_node_make(NODE_TEXT,(yyvsp[(1) - (1)].str),NULL); ;}
break;
case 81:
......@@ -2718,7 +2718,7 @@ yyreduce:
/* Line 1455 of yacc.c */
#line 296 "SCDoc.y"
{ (yyval.doc_node) = doc_node_create("NL"); ;}
{ (yyval.doc_node) = doc_node_create(NODE_NL); ;}
break;
case 85:
......
......@@ -289,11 +289,11 @@ prose: prose proseelem { $$ = doc_node_add_child($1, $2); }
| proseelem { $$ = doc_node_make("PROSE",NULL,$1); }
;
proseelem: anyword { $$ = doc_node_make("TEXT",$1,NULL); } // one TEXT for each word
proseelem: anyword { $$ = doc_node_make(NODE_TEXT,$1,NULL); } // one TEXT for each word
| URL { $$ = doc_node_make("LINK",$1,NULL); }
| inlinetag words TAGSYM { $$ = doc_node_make($1,$2,NULL); }
| FOOTNOTE body TAGSYM { $$ = doc_node_make_take_children("FOOTNOTE",NULL,$2); }
| NEWLINE { $$ = doc_node_create("NL"); }
| NEWLINE { $$ = doc_node_create(NODE_NL); }
;
inlinetag: LINK { $$ = "LINK"; }
......
......@@ -3,4 +3,4 @@
set(PROJECT_VERSION_MAJOR 3)
set(PROJECT_VERSION_MINOR 5)
set(PROJECT_VERSION_PATCH .3)
set(PROJECT_VERSION_PATCH .4)
......@@ -282,7 +282,7 @@ namespace boost
# endif
# endif
# ifdef BOOST_BIG_ENDIAN
endian & operator=(T val) { m_value = val); return *this; }
endian & operator=(T val) { m_value = val; return *this; }
operator T() const { return m_value; }
# else
endian & operator=(T val) { detail::store_big_endian<T, sizeof(T)>(&m_value, val); return *this; }
......
......@@ -32,6 +32,7 @@
// replacement for calloc.
// calloc lazily zeroes memory on first touch. This is good for most purposes, but bad for realtime audio.
void* zalloc(size_t n, size_t size);
void zfree(void* ptr);
////////////////////////////////////////////////////////////////////////
......
......@@ -1646,6 +1646,8 @@ int prSFOpenWrite(struct VMGlobals *g, int numArgsPushed)
slotIntVal(slotRawObject(a)->slots + 5, &info.samplerate);
file = sf_open(filename, SFM_WRITE, &info);
sf_command(file, SFC_SET_CLIPPING, NULL, SF_TRUE);
if (file) {
SetPtr(slotRawObject(a)->slots+0, file);
SetTrue(a);
......
......@@ -39,7 +39,8 @@ if [ $package_type == "source" ]; then
fi
returndir=`pwd`
cd ../
bash package/git-archive-all.sh --prefix SuperCollider-Source/ "$returndir/SuperCollider-Source.tmp.tar"
python package/git-archive-all.py --prefix SuperCollider-Source/ "$returndir/SuperCollider-Source.tmp.tar"
cd "$returndir"
# NB we only need one instance of boost, so we exclude one of its two appearances as a submodule in the following
tar -x --exclude ".gitignore" --exclude ".gitmodules" \
......
......@@ -241,14 +241,27 @@ inline double sc_gloop(double in, double hi)
windowGuardFrame = windowFrames - 1; \
} while (0);
#define GET_GRAIN_WIN(WINTYPE) \
do { \
if (WINTYPE >= unit->mWorld->mNumSndBufs) { \
Print("Envelope buffer out of range!\n"); \
return; \
} \
GET_GRAIN_WIN_RELAXED(WINTYPE) \
} while (0);
static inline bool getGrainWin(Unit * unit, float wintype, SndBuf *& window, const float * & windowData,
uint32 & windowSamples, uint32 & windowFrames, int & windowGuardFrame)
{
if (wintype >= unit->mWorld->mNumSndBufs) {
Print("Envelope buffer out of range!\n");
return false;
}
assert(wintype < unit->mWorld->mNumSndBufs);
window = unit->mWorld->mSndBufs + (int)wintype;
windowData = window->data;
if (!windowData)
return false;
windowSamples = window->samples;
windowFrames = window->frames;
windowGuardFrame = windowFrames - 1;
return true;
}
#define GRAIN_LOOP_BODY_4 \
float amp = y1 * y1; \
......@@ -534,8 +547,8 @@ inline void GrainIn_next_start_new(GrainIn * unit, int inNumSamples, int positio
float winType = grain_in_at<full_rate>(unit, 4, position);
DECLARE_WINDOW
GET_GRAIN_WIN(winType)
if (winType >= 0 && (windowData == NULL))
bool success = getGrainWin(unit, winType, window, windowData, windowSamples, windowFrames, windowGuardFrame);
if (!success)
return;
GrainInG *grain = unit->mGrains + unit->mNumActive++;
......@@ -683,8 +696,8 @@ inline void GrainSin_next_start_new(GrainSin * unit, int inNumSamples, int posit
float winType = grain_in_at<full_rate>(unit, 4, position);
DECLARE_WINDOW
GET_GRAIN_WIN(winType)
if (winType >= 0 && (windowData == NULL))
bool success = getGrainWin(unit, winType, window, windowData, windowSamples, windowFrames, windowGuardFrame);
if (!success)
return;
GrainSinG *grain = unit->mGrains + unit->mNumActive++;
......@@ -850,8 +863,8 @@ inline void GrainFM_next_start_new(GrainFM * unit, int inNumSamples, int positio
float winType = grain_in_at<full_rate>(unit, 6, position);
DECLARE_WINDOW
GET_GRAIN_WIN(winType)
if (winType >= 0 && (windowData == NULL))
bool success = getGrainWin(unit, winType, window, windowData, windowSamples, windowFrames, windowGuardFrame);
if (!success)
return;
GrainFMG *grain = unit->mGrains + unit->mNumActive++;
......@@ -1090,10 +1103,10 @@ static inline void GrainBuf_next_play_active(GrainBuf *unit, int inNumSamples)
GRAIN_BUF
if (!bufData) {
if (!bufData || (bufChannels != 1)) {
grain->counter -= inNumSamples;
if (!GrainBuf_grain_cleanup(unit, grain))
++i;
++i;
continue;
}
......@@ -1104,6 +1117,8 @@ static inline void GrainBuf_next_play_active(GrainBuf *unit, int inNumSamples)
DECLARE_WINDOW
GET_GRAIN_AMP_PARAMS
// begin add //
float pan2 = 0.f;
float *out2;
......@@ -1139,9 +1154,11 @@ static inline void GrainBuf_next_start_new(GrainBuf *unit, int inNumSamples, int
GrainBufG *grain = unit->mGrains + unit->mNumActive++;
float winType = grain_in_at<full_rate>(unit, 7, position);
DECLARE_WINDOW
GET_GRAIN_WIN(winType)
if (winType >= 0 && (windowData == NULL))
bool success = getGrainWin(unit, winType, window, windowData, windowSamples, windowFrames, windowGuardFrame);
if (!success) {
GrainBuf_grain_cleanup(unit, grain);
return;
}
int32 bufnum = grain_in_at<full_rate>(unit, 2, position);
grain->bufnum = bufnum;
......
......@@ -319,7 +319,7 @@ bool BufAllocCmd::Stage3()
void BufAllocCmd::Stage4()
{
free(mFreeData);
zfree(mFreeData);
SendDoneWithIntValue("/b_alloc", mBufIndex);
}
......@@ -385,7 +385,7 @@ bool BufGenCmd::Stage3()
void BufGenCmd::Stage4()
{
free(mFreeData);
zfree(mFreeData);
SendDoneWithIntValue("/b_gen", mBufIndex);
}
......@@ -440,7 +440,7 @@ bool BufFreeCmd::Stage3()
void BufFreeCmd::Stage4()
{
free(mFreeData);
zfree(mFreeData);
SendDoneWithIntValue("/b_free", mBufIndex);
}
......@@ -575,7 +575,7 @@ bool BufAllocReadCmd::Stage3()
void BufAllocReadCmd::Stage4()
{
free(mFreeData);
zfree(mFreeData);
SendDoneWithIntValue("/b_allocRead", mBufIndex);
}