void ramp_setFunction(t_ramp *x, void *attr, long argc, t_atom *argv) { long n; TTValue names; TTSymbol* aName; TTString nameString; // set the function x->attr_function = atom_getsym(argv); x->rampUnit->setAttributeValue(TT("function"), TT(x->attr_function->s_name)); // cache the function's attribute names x->parameterNames->clear(); x->rampUnit->getFunctionParameterNames(names); n = names.getSize(); for (int i=0; i<n; i++) { names.get(i, &aName); nameString = aName->getString(); if (aName == TT("bypass") || aName == TT("mute") || aName == TT("maxNumChannels") || aName == TT("sampleRate")) continue; // don't publish these parameters if (nameString[0] > 64 && nameString[0] < 91) { // ignore all params not starting with upper-case nameString[0] += 32; // convert first letter to lower-case for Max TTValuePtr v = new TTValue(aName); x->parameterNames->append(TT(nameString.c_str()), *v); } } }
void plug_alias_register(const char* plugtastic_name, const char* original_name, const char* category, const char* description) { t_atom a[4]; TTString str = "Plugtastic "; // create alias object_method(sMaxObject, ps_objectfile, GENSYM(plugtastic_name), GENSYM(original_name), GENSYM(original_name)); // add to autocompletion atom_setsym(a, GENSYM(plugtastic_name)); object_method_typed(sMaxObject, ps_db_object_addinternal, 1, a, NULL); // add to object list str += category; object_method(sMaxObject, ps_oblist, GENSYM(str.c_str()), GENSYM(plugtastic_name)); atom_setsym(a+0, GENSYM(plugtastic_name)); atom_setsym(a+1, _sym_object); atom_setsym(a+2, _sym_tag); atom_setsym(a+3, GENSYM("Plugtastic")); object_method_typed(sMaxObject, ps_db_addmetadata, 4, a, NULL); atom_setsym(a+0, GENSYM(plugtastic_name)); atom_setsym(a+1, _sym_object); atom_setsym(a+2, _sym_tag); atom_setsym(a+3, GENSYM(category)); object_method_typed(sMaxObject, ps_db_addmetadata, 4, a, NULL); atom_setsym(a+0, GENSYM(plugtastic_name)); atom_setsym(a+1, _sym_object); atom_setsym(a+2, _sym_description); atom_setsym(a+3, GENSYM(description)); object_method_typed(sMaxObject, ps_db_addmetadata, 4, a, NULL); }
void wrappedClass_receiveNotificationForOutlet(WrappedInstancePtr self, TTValue& arg) { TTString string = arg[0]; t_symbol* s = gensym((char*)string.c_str()); outlet_anything((t_outlet*)self->controlOutlet, s, 0, NULL); }
TTErr TTValue::transformCSVStringToSymbolArray() { TTString str; char* cStr; char* current; if (*type != kTypeString) return kTTErrInvalidType; str = *data->stringPtr; clear(); cStr = new char[str.size()+1]; strncpy(cStr, str.c_str(), str.size()+1); current = strrchr(cStr, ','); while (current) { *current = 0; current++; // Do some basic whitespace stripping from the ends while (*current == ' ') current++; while (current[strlen(current)-1] == ' ') current[strlen(current)-1] = 0; append(TT(current)); current = strrchr(cStr, ','); } append(TT(cStr)); delete[] cStr; return kTTErrNone; }
void WrappedInputClass_new(TTPtr self, AtomCount argc, AtomPtr argv) { WrappedModularInstancePtr x = (WrappedModularInstancePtr)self; long attrstart = attr_args_offset(argc, argv); // support normal arguments TTString sInstance; TTValue v; // Prepare extra data x->extra = (t_extra*)malloc(sizeof(t_extra)); // Get input instance symbol if (attrstart && argv) { jamoma_ttvalue_from_Atom(v, _sym_nothing, attrstart, argv); v.toString(); sInstance = TTString(v[0]); EXTRA->instance = TTSymbol(sInstance.data()); } else EXTRA->instance = kTTSymEmpty; // Create Input Object and one outlet x->outlets = (TTHandle)sysmem_newptr(sizeof(TTPtr)); #ifdef JCOM_IN_TILDE jamoma_input_create_audio((ObjectPtr)x, &x->wrappedObject); dsp_setup((t_pxobject *)x, 1); x->obj.z_misc = Z_NO_INPLACE | Z_PUT_FIRST; outlet_new((t_pxobject *)x, "signal"); // Prepare memory to store internal datas x->internals = new TTHash(); // Prepare extra data for envelope tracking EXTRA->clock = NULL; EXTRA->pollInterval = 0; // not active by default EXTRA->meter = 0.; EXTRA->peak = 0.; #else jamoma_input_create((ObjectPtr)x, &x->wrappedObject); x->outlets[0] = outlet_new(x, 0L); #endif // handle attribute args attr_args_process(x, argc, argv); // The following must be deferred because we have to interrogate our box, // and our box is not yet valid until we have finished instantiating the object. // Trying to use a loadbang method instead is also not fully successful (as of Max 5.0.6) defer_low((ObjectPtr)x, (method)in_subscribe, NULL, 0, NULL); }
void WrappedOutputClass_new(TTPtr self, long argc, t_atom* argv) { WrappedModularInstancePtr x = (WrappedModularInstancePtr)self; long attrstart = attr_args_offset(argc, argv); // support normal arguments TTString sInstance; TTValue v; // Prepare extra data x->extra = (t_extra*)malloc(sizeof(t_extra)); // Get input instance symbol if (attrstart && argv) { jamoma_ttvalue_from_Atom(v, _sym_nothing, attrstart, argv); v.toString(); sInstance = TTString(v[0]); EXTRA->instance = TTSymbol(sInstance.data()); } else EXTRA->instance = kTTSymEmpty; // Create Input Object and one outlet x->outlets = (TTHandle)sysmem_newptr(sizeof(TTPtr)); #ifdef J_OUT_TILDE jamoma_output_create_audio((t_object*)x, x->wrappedObject); dsp_setup((t_pxobject *)x, 1); x->obj.z_misc = Z_NO_INPLACE | Z_PUT_FIRST; outlet_new((t_pxobject *)x, "signal"); #endif #ifdef J_OUT_MULTI jamoma_output_create_audio((t_object*)x, x->wrappedObject); x->outlets[0] = outlet_new(x, 0L); #endif #ifndef J_OUT_TILDE #ifndef J_OUT_MULTI jamoma_output_create((t_object*)x, x->wrappedObject); x->outlets[0] = outlet_new((t_object*)x, 0L); #endif #endif // handle attribute args attr_args_process(x, argc, argv); // The following must be deferred because we have to interrogate our box, // and our box is not yet valid until we have finished instantiating the object. // Trying to use a loadbang method instead is also not fully successful (as of Max 5.0.6) // out_subscribe(x); // defer_low((t_object*)x, (method)out_subscribe, NULL, 0, NULL); }
void addAttributeToXml(TTObjectPtr param, XMLNode xmlNode, TTSymbolPtr attrName) { TTValue v, vDescr; TTString s; TTSymbolPtr descr; // get the Value of an attribute and format to string v.clear(); param->getAttributeValue(attrName, v); param->getAttributeValue(kTTSym_description, vDescr); vDescr.get(0, &descr); if (attrName == kTTSym_type && descr == TTSymbol("filepath")) { xmlNode.addAttribute_(attrName->getCString(), "filepath"); } else { v.toString(); v.get(0, s); // add this attribute in xml tree xmlNode.addAttribute_(attrName->getCString(), s.data()); } }
TTErr TTData::WriteAsText(const TTValue& inputValue, TTValue& outputValue) { TTObject o = inputValue[0]; TTTextHandlerPtr aTextHandler = (TTTextHandlerPtr)o.instance(); if (!aTextHandler) return kTTErrGeneric; TTString *buffer; TTValue toString; TTString line; buffer = aTextHandler->mWriter; // Type *buffer += "\t\t\t<td class =\"instructionType\">"; *buffer += this->mType.c_str(); *buffer += "</td>"; // range/bounds toString = this->mRangeBounds; toString.toString(); line = TTString(toString[0]); if ( (this->mType == kTTSym_integer) || (this->mType == kTTSym_boolean) || (this->mType == kTTSym_decimal) || (this->mType == kTTSym_generic) ) { *buffer +="\t\t\t<td class =\"instructionRangeBounds\">"; *buffer +=line.data(); *buffer += "</td>"; } else *buffer += "\t\t\t<td class = \"instructionRangeBounds\"> N/A </td>"; // clipmode *buffer += "\t\t\t<td class =\"instructionRangeClipmode\">"; *buffer += this->mRangeClipmode.c_str(); *buffer += "</td>"; // ramp/drive *buffer += "\t\t\t<td class =\"instructionRampDrive\">"; *buffer += this->mRampDrive.c_str(); *buffer += "</td>"; #ifndef TT_NO_DSP // ramp/function *buffer += "\t\t\t<td class =\"instructionRampFunction\">"; *buffer += this->mRampFunction.c_str(); *buffer += "</td>"; #endif // dataspace *buffer += "\t\t\t<td class =\"instructionDataspace\">"; *buffer += this->mDataspace.c_str(); *buffer += "</td>"; // dataspace/unit *buffer += "\t\t\t<td class =\"instructionDataspaceUnit\">"; *buffer += this->mDataspaceUnit.c_str(); *buffer += "</td>"; // repetitions/filter toString = this->mRepetitionsFilter; toString.toString(); line = TTString(toString[0]); *buffer += "\t\t\t<td class =\"instructionRepetitionsFilter\">"; *buffer += line.data(); *buffer += "</td>"; // description *buffer += "\t\t\t<td class =\"instructionDescription\">"; *buffer += this->mDescription.c_str(); *buffer += "</td>"; return kTTErrNone; }
TTErr TTSoundfileLoader::test(TTValue& returnedTestInfo) { int errorCount = 0; int testAssertionCount = 0; // assemble the full path of the target sound file TTString testSoundPath = TTFoundationBinaryPath; int pos = testSoundPath.find_last_of('/'); testSoundPath = testSoundPath.substr(0,pos+1); testSoundPath += TESTFILE; std::cout << "We will be using the following path for testing: " << testSoundPath << "\n"; try { TTTestLog("\n"); TTTestLog("Testing TTSoundfileLoader Basics..."); // TEST 0: establish our objects & pointers TTObject* testTargetMatrix = new TTObject("samplematrix"); TTObject* testNonSampleMatrix = new TTObject("delay"); TTObjectBase* objectBasePtrToSampleMatrix; TTObjectBase* ptrToNonSampleMatrix; // TEST 1: set the filepath TTBoolean result1 = { this->setFilePath(TT(testSoundPath)) == kTTErrNone }; TTTestAssertion("setFilePath operates successfully", result1, testAssertionCount, errorCount); // TEST 2: set up the samplematrix first int channelsSend = 1; // compiler complained about TTInt32 being ambiguous here int lengthSend = 22050; // compiler complained about TTInt32 being ambiguous here testTargetMatrix->set("numChannels", channelsSend); testTargetMatrix->set("lengthInSamples", lengthSend); TTInt32 channelsReturn, lengthReturn; testTargetMatrix->get("numChannels", channelsReturn); testTargetMatrix->get("lengthInSamples", lengthReturn); // now for the actual test TTBoolean result2a = { channelsSend == channelsReturn }; TTTestAssertion("numChannels attribute set successfully", result2a, testAssertionCount, errorCount); TTBoolean result2b = { lengthSend == lengthReturn }; TTTestAssertion("lengthInSamples attribute set successfully", result2b, testAssertionCount, errorCount); // // TEST 3: set the target via an objectBasePtr objectBasePtrToSampleMatrix = testTargetMatrix->instance(); // is there a better syntax for this? TTBoolean result3 = { this->setTargetMatrix(objectBasePtrToSampleMatrix) == kTTErrNone }; TTTestAssertion("setTargetMatrix via ObjectBasePtr operates successfully", result3, testAssertionCount, errorCount); // TEST 4: set the target to a non-SampleMatrix, should FAIL ptrToNonSampleMatrix = testNonSampleMatrix->instance(); TTBoolean result4 = { this->setTargetMatrix(ptrToNonSampleMatrix) == kTTErrInvalidValue }; TTTestAssertion("setTargetMatrix returns error when not a SampleMatrix", result4, testAssertionCount, errorCount); // TEST 5: copy samplevalues until samplematrix is filled TTBoolean result5 = { this->copyUntilFilled() == kTTErrNone }; TTTestAssertion("copyUntilFilled operates successfully", result5, testAssertionCount, errorCount); // releasing objects objectBasePtrToSampleMatrix = NULL; ptrToNonSampleMatrix = NULL; delete testTargetMatrix; delete testNonSampleMatrix; // TEST 6: use TTSampleMatrix's load message, then compare 5 random sample values for equivalence // create a new TTSampleMatrix TTObject newTargetMatrix("samplematrix"); // set the length and channel count newTargetMatrix.set("numChannels", TESTNUMCHANNELS); newTargetMatrix.set("lengthInSamples", TESTDURATIONINSAMPLES); // prepare necessary TTValues TTValue loadInput6 = TT(testSoundPath); // we cannot pass the naked TTString, it needs to be part of a TTValue TTValue aReturnWeDontCareAbout6; // send message TTBoolean result6a = { newTargetMatrix.send("load", loadInput6, aReturnWeDontCareAbout6) == kTTErrNone }; TTTestAssertion("TTSampleMatrix load operates successfully", result6a, testAssertionCount, errorCount); // now let's test some values! int randomIndex6, randomChannel6; TTSampleValue testValueSoundFile6; TTBoolean result6b = true; for (int i = 0; i<10; i++) { randomIndex6 = lengthReturn * TTRandom64(); randomChannel6 = i % TESTNUMCHANNELS; //std::cout << "let's look at index " << randomIndex6 << " & channel " << randomChannel6 << "\n"; TTValue peekInput6(randomIndex6); peekInput6.append(randomChannel6); TTValue peekOutput6; this->peek(randomIndex6,randomChannel6,testValueSoundFile6); newTargetMatrix.send("peek",peekInput6,peekOutput6); //std::cout << "Does " << testValueSoundFile6 << " = " << double(peekOutput6) << " ?\n"; if (result6b) // allows test to keep variable false once it is false result6b = TTTestFloatEquivalence(testValueSoundFile6, double(peekOutput6), true, 0.0000001); } TTTestAssertion("comparing values @ 10 random indexes for equivalence", result6b, testAssertionCount, errorCount); // TEST 7: now use TTBuffer's load message, and again compare 5 random sample values for equivalence // create a new TTBuffer with convenience syntax TTAudioBuffer aBufferByAnyOtherName(TESTNUMCHANNELS, TESTDURATIONINSAMPLES); // prepare necessary TTValues TTValue loadInput7 = TT(testSoundPath); // we cannot pass the naked TTString, it needs to be part of a TTValue // send message TTBoolean result7a = { aBufferByAnyOtherName.load(loadInput7) == kTTErrNone }; TTTestAssertion("TTBuffer load operates successfully", result7a, testAssertionCount, errorCount); // setup pointer to samplematrix TTSampleMatrixPtr myMatrix7; // check out samplematrix TTBoolean result7b = { aBufferByAnyOtherName.checkOutMatrix(myMatrix7) == kTTErrNone }; TTTestAssertion("TTBuffer checks out SampleMatrix successfully", result7b, testAssertionCount, errorCount); TTValue testChannel, testSample; myMatrix7->getNumChannels(testChannel); myMatrix7->getLengthInSamples(testSample); //std::cout << "Samplematrix has " << int(testChannel) << " channels & " << int(testSample) << " samples\n"; // now let's test some values! int randomIndex7, randomChannel7; double testValueSoundFile7, testValueSampleMatrix7; TTBoolean result7c = true; for (int i = 0; i<10; i++) { randomIndex7 = lengthReturn * TTRandom64(); randomChannel7 = i % TESTNUMCHANNELS; //std::cout << "let's look at index " << randomIndex7 << " & channel " << randomChannel7 << "\n"; this->peek(randomIndex7,randomChannel7,testValueSoundFile7); myMatrix7->peek(randomIndex7,randomChannel7,testValueSampleMatrix7); //std::cout << "Does " << testValueSoundFile7 << " = " << testValueSampleMatrix7 << " ?\n"; if (result7c) // allows test to keep variable false once it is false result7c = TTTestFloatEquivalence(testValueSoundFile7, testValueSampleMatrix7, true, 0.0000001); } TTTestAssertion("comparing values @ 10 random indexes for equivalence", result7c, testAssertionCount, errorCount); // check in samplematrix TTBoolean result7d = { aBufferByAnyOtherName.checkInMatrix(myMatrix7) == kTTErrNone }; TTTestAssertion("TTBuffer checks in SampleMatrix successfully", result7d, testAssertionCount, errorCount); // TEST 8: use optional load parameters to copy samples 5 to 15 from channel 0 // resize aBufferByAnyOtherName.set("numChannels", 1); aBufferByAnyOtherName.set("lengthInSamples", 10); // prepare necessary TTValues int copyChannel8 = 0; // first channel int startIndex8 = 5; // start @ sample 5 int endIndex8 = 15; // end @ sample 15 TTValue loadInput8 = TT(testSoundPath); // we cannot pass the naked TTString, it needs to be part of a TTValue loadInput8.append(copyChannel8); loadInput8.append(startIndex8); loadInput8.append(endIndex8); // send message TTBoolean result8a = { aBufferByAnyOtherName.load(loadInput8) == kTTErrNone }; TTTestAssertion("TTBuffer load operates successfully w optional parameters", result8a, testAssertionCount, errorCount); // setup pointer to samplematrix TTSampleMatrixPtr myMatrix8; // check out samplematrix TTBoolean result8b = { aBufferByAnyOtherName.checkOutMatrix(myMatrix8) == kTTErrNone }; TTTestAssertion("TTBuffer checks out SampleMatrix successfully", result8b, testAssertionCount, errorCount); // now let's test some values! double testValueSoundFile8, testValueSampleMatrix8; TTBoolean result8c = true; for (int i = 0; i<10; i++) { //std::cout << "let's look at index " << i << "\n"; this->peek(i+startIndex8,copyChannel8,testValueSoundFile8); myMatrix8->peek(i,copyChannel8,testValueSampleMatrix8); //std::cout << "Does " << testValueSoundFile8 << " = " << testValueSampleMatrix8 << " ?\n"; if (result8c) // allows test to keep variable false once it is false result8c = TTTestFloatEquivalence(testValueSoundFile8, testValueSampleMatrix8, true, 0.0000001); } TTTestAssertion("comparing all 10 copied values for equivalence", result8c, testAssertionCount, errorCount); // check in samplematrix TTBoolean result8d = { aBufferByAnyOtherName.checkInMatrix(myMatrix8) == kTTErrNone }; TTTestAssertion("TTBuffer checks in SampleMatrix successfully", result8d, testAssertionCount, errorCount); // TEST 9: load soundfile into buffer/samplematrix with different sample rate TTValue testChannel9in = 2; TTValue testSampleRate9in = 88200; TTValue testLengthSec9in = 0.25; aBufferByAnyOtherName.set("numChannels", testChannel9in); aBufferByAnyOtherName.set("sampleRate", testSampleRate9in); aBufferByAnyOtherName.set("lengthInSeconds", testLengthSec9in); TTValue loadInput9 = TT(testSoundPath); // we cannot pass the naked TTString, it needs to be part of a TTValue // send message TTBoolean result9a = { aBufferByAnyOtherName.load(loadInput9) == kTTErrNone }; TTTestAssertion("TTBuffer load operates successfully when sample rates differ", result9a, testAssertionCount, errorCount); // setup pointer to samplematrix TTSampleMatrixPtr myMatrix9; // check out samplematrix TTBoolean result9b = { aBufferByAnyOtherName.checkOutMatrix(myMatrix9) == kTTErrNone }; TTTestAssertion("TTBuffer checks out SampleMatrix successfully", result9b, testAssertionCount, errorCount); TTValue testChannel9, testSampleCount9, testSampleRate9; myMatrix9->getAttributeValue("numChannels", testChannel9); myMatrix9->getAttributeValue("lengthInSamples", testSampleCount9); myMatrix9->getAttributeValue("sampleRate", testSampleRate9); /*std::cout << "Samplematrix has " << TTInt32(testChannel9) << " channels & " << TTInt32(testSampleCount9) << " samples @ " << TTInt32(testSampleRate9) << " Hz\n";*/ // check out samplematrix TTBoolean result9c = { TTInt32(testChannel9) == TTInt32(testChannel9in) && TTInt32(testSampleRate9) == TTInt32(testSampleRate9in) && TTInt32(testSampleCount9) == (TTInt32(testSampleRate9in) * TTFloat64(testLengthSec9in)) }; TTTestAssertion("SampleMatrix has same attributes set via TTBuffer", result9c, testAssertionCount, errorCount); // let's test some values int randomIndex9, randomChannel9; TTSampleValue testSoundFileValue9, testSampleMatrixValue9; TTBoolean result9d = true; for (int i = 0; i<10; i++) { randomIndex9 = int(testSampleCount9) * TTRandom64(); randomChannel9 = i % TESTNUMCHANNELS; //std::cout << "let's look at index " << randomIndex9 << " & channel " << randomChannel9 << "\n"; this->peeki(float(randomIndex9)/2.0, randomChannel9, testSoundFileValue9); myMatrix9->peek(randomIndex9, randomChannel9, testSampleMatrixValue9); //std::cout << "Does " << testSoundFileValue9 << " = " << testSampleMatrixValue9 << " ?\n"; if (result9d) // allows test to keep variable false once it is false result9d = TTTestFloatEquivalence(testSoundFileValue9, testSampleMatrixValue9, true, 0.0000001); } TTTestAssertion("comparing values @ 10 random indexes for equivalence", result9d, testAssertionCount, errorCount); // check in samplematrix TTBoolean result9e = { aBufferByAnyOtherName.checkInMatrix(myMatrix9) == kTTErrNone }; TTTestAssertion("TTBuffer checks in SampleMatrix successfully", result9e, testAssertionCount, errorCount); // TEST 10: use resizeThenLoad message and test that TTSampleMatrix conforms to sound file loaded TTAudioBuffer bufferForTest10(1,1); // start by making the buffer really tiny TTValue loadInput10 = TT(testSoundPath); // send message TTBoolean result10a = { bufferForTest10.resizeThenLoad(loadInput10) == kTTErrNone }; TTTestAssertion("TTBuffer resizeThenLoad operates successfully", result10a, testAssertionCount, errorCount); // setup pointer to samplematrix TTSampleMatrixPtr myMatrix10; // check out samplematrix TTBoolean result10b = { bufferForTest10.checkOutMatrix(myMatrix10) == kTTErrNone }; TTTestAssertion("TTBuffer checks out SampleMatrix successfully", result10b, testAssertionCount, errorCount); // do some more tests here TTValue testChannel10, testLengthSec10, testLengthSample10; myMatrix10->getAttributeValue("numChannels", testChannel10); myMatrix10->getAttributeValue("lengthInSeconds", testLengthSec10); myMatrix10->getAttributeValue("lengthInSamples", testLengthSample10); /*std::cout << "Samplematrix has " << TTInt32(testChannel10) << " channels & " << TTInt32(testLengthSample10) << " samples and is " << TTFloat64(testLengthSec10) << " secs long\n";*/ TTBoolean result10c = { TTInt32(testChannel10) == TESTNUMCHANNELS && TTInt32(testLengthSample10) == TESTDURATIONINSAMPLES }; TTTestAssertion("TTBuffer.resizeThenLoad results in properly sized TTSampleMatrix", result10c, testAssertionCount, errorCount); // check in samplematrix TTBoolean result10e = { bufferForTest10.checkInMatrix(myMatrix10) == kTTErrNone }; TTTestAssertion("TTBuffer checks in SampleMartix successfully", result10e, testAssertionCount, errorCount); } catch (...) { TTTestAssertion("FAILED to run tests -- likely that necessary objects did not instantiate", 0, testAssertionCount, errorCount); } return TTTestFinish(testAssertionCount, errorCount, returnedTestInfo); }
void cue_edit(TTPtr self, t_symbol *msg, long argc, const t_atom *argv) { WrappedModularInstancePtr x = (WrappedModularInstancePtr)self; TTString *buffer; char title[MAX_FILENAME_CHARS]; TTObject aTextHandler; TTHashPtr allCues; TTValue v, o; TTSymbol name = kTTSymEmpty; t_atom a; TTErr tterr; // choose object to edit : default the cuelist *EXTRA->toEdit = x->wrappedObject; EXTRA->cueName = kTTSymEmpty; if (argc && argv) { if (atom_gettype(argv) == A_LONG) { TTUInt32 index = atom_getlong(argv); // get cues names x->wrappedObject.get("names", v); if (index > 0 && index <= v.size()) name = v[index-1]; else { object_error((t_object*)x, "%d doesn't exist", atom_getlong(argv)); return; } } else if (atom_gettype(argv) == A_SYM) name = TTSymbol(atom_getsym(argv)->s_name); if (name != kTTSymEmpty) { // get cue object table x->wrappedObject.get("cues", v); allCues = TTHashPtr((TTPtr)v[0]); if (allCues) { // get cue to edit if (!allCues->lookup(name, v)) { // edit a cue *EXTRA->toEdit = v[0]; EXTRA->cueName = name; } else { object_error((t_object*)x, "%s doesn't exist", atom_getsym(argv)->s_name); return; } } } } // only one editor can be open in the same time if (!EXTRA->textEditor) { EXTRA->textEditor = (t_object*)object_new(_sym_nobox, _sym_jed, x, 0); buffer = new TTString(); // get the buffer handler tterr = x->internals->lookup(kTTSym_TextHandler, o); if (!tterr) { aTextHandler = o[0]; critical_enter(0); aTextHandler.set(kTTSym_object, *EXTRA->toEdit); tterr = aTextHandler.send(kTTSym_Write, (TTPtr)buffer); critical_exit(0); } // pass the buffer to the editor object_method(EXTRA->textEditor, _sym_settext, buffer->c_str(), _sym_utf_8); object_attr_setchar(EXTRA->textEditor, gensym("scratch"), 1); snprintf(title, MAX_FILENAME_CHARS, "cuelist editor"); object_attr_setsym(EXTRA->textEditor, _sym_title, gensym(title)); // output a flag atom_setsym(&a, gensym("opened")); object_obex_dumpout(self, gensym("editor"), 1, &a); buffer->clear(); delete buffer; buffer = NULL; } else { object_attr_setchar(EXTRA->textEditor, gensym("visible"), 1); } }
void TTFoundationLoadExternalClasses() { #ifdef TT_PLATFORM_MAC OSErr err = noErr; FSRef ref; UInt8 path[4096]; TTString fullpath; // Look in ~/Library/Application Support/TTBlue/Extensions err = FSFindFolder(kLocalDomain, kApplicationSupportFolderType, kCreateFolder, &ref); if (!err) { FSRefMakePath(&ref, path, 4096); fullpath = (char*)path; fullpath += "/Jamoma/Extensions"; TTFoundationLoadExternalClassesFromFolder(fullpath); } // Look in /Library/Application Support/TTBlue/Extensions err = FSFindFolder(kUserDomain, kApplicationSupportFolderType, kCreateFolder, &ref); if (!err) { FSRefMakePath(&ref, path, 4096); fullpath = (char*)path; fullpath += "/Jamoma/Extensions"; TTFoundationLoadExternalClassesFromFolder(fullpath); } // Look in the folder of the host application CFBundleRef mainBundle = CFBundleGetMainBundle(); CFURLRef mainBundleURL = CFBundleCopyBundleURL(mainBundle); CFStringRef mainBundlePath = CFURLCopyFileSystemPath(mainBundleURL, kCFURLPOSIXPathStyle); char mainBundleStr[4096]; CFStringGetCString(mainBundlePath, mainBundleStr, 4096, kCFStringEncodingUTF8); strncat(mainBundleStr, "/Contents/Jamoma/Extensions", 4096); mainBundleStr[4095] = 0; TTFoundationLoadExternalClassesFromFolder(mainBundleStr); #elif TT_PLATFORM_WIN TTString fullpath; char temppath[4096]; // WCHAR wc[4096]; HKEY hKey = 0; LONG lRes; DWORD dwSize = sizeof(temppath); HRESULT hr; HINSTANCE hInstance = GetModuleHandle(NULL); // Look in C:\Program Files\Common Files\TTBlue\Extensions hr = SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES_COMMON, NULL, SHGFP_TYPE_CURRENT, (LPSTR)temppath); if (!FAILED(hr)) { fullpath = temppath; fullpath += "\\Jamoma\\Extensions\\"; lRes = SHCreateDirectory(NULL, (LPCWSTR)fullpath.c_str()); TTFoundationLoadExternalClassesFromFolder(fullpath); } // TODO: Look in some user-level directory like we do on the Mac? // Look in the support folder of the host application if (hInstance) { GetModuleFileName(hInstance, (LPSTR)temppath, 4096); if (temppath[0]) { char *s = strrchr(temppath, '\\'); if (s) *s = 0; fullpath = temppath; fullpath += "\\Jamoma\\Extensions\\"; lRes = SHCreateDirectory(NULL, (LPCWSTR)fullpath.c_str()); TTFoundationLoadExternalClassesFromFolder(fullpath); } } #else // Some other platform, like Linux #endif }
void TTFoundationLoadExternalClassesFromFolder(const TTString& fullpath) { #ifdef TT_PLATFORM_MAC FSRef ref; Boolean isDirectory; OSStatus status = noErr; ItemCount count = 0; FSIterator iterator; HFSUniStr255* names = NULL; CFStringRef name; char cname[4096]; TTString path; TTCString cpath = (char*)fullpath.c_str(); void* handle; TTExtensionInitializationMethod initializer; TTErr err; status = FSPathMakeRef((UInt8*)cpath, &ref, &isDirectory); if (status != noErr) { #ifdef TT_DEBUG TTLogMessage("TTFoundation - no extensions location found @ %s\n", cpath); #endif return; } status = FSOpenIterator(&ref, kFSIterateFlat, &iterator); if (!status) { names = (HFSUniStr255 *)malloc(sizeof(HFSUniStr255) * 4096); if (names) { // Request information about files in the given directory, // until we get a status code back from the File Manager do{ status = FSGetCatalogInfoBulk(iterator, 4096, &count, NULL, kFSCatInfoNone, NULL, NULL, NULL, names); // Process all items received if (status == OSStatus(noErr) || status == OSStatus(errFSNoMoreItems)) { for (UInt32 i=0; i < count; i += 1) { name = CFStringCreateWithCharacters(kCFAllocatorDefault, names[i].unicode, names[i].length); // TODO: filter on name. We only want to try and load .ttdylib files CFStringGetCString(name, cname, 4096, kCFStringEncodingUTF8); path = fullpath; path += "/"; path += cname; handle = dlopen(path.c_str(), RTLD_LAZY); // TODO: assert -- or at least do a log post -- if handle is NULL initializer = (TTExtensionInitializationMethod)dlsym(handle, "loadTTExtension"); if (initializer) err = initializer(); CFRelease(name); } } } while (status == OSStatus(noErr)); // errFSNoMoreItems tells us we have successfully processed all // items in the directory -- not really an error if (status == OSStatus(errFSNoMoreItems)) status = noErr; // Free the array memory free( (void *) names ); } FSCloseIterator(iterator); } #elif TT_PLATFORM_WIN HANDLE fdHandle; WIN32_FIND_DATA findFileData; TTString path; HANDLE hLib = NULL; TTExtensionInitializationMethod initializer; TTErr err; path = fullpath; path += "*.ttdll"; fdHandle = FindFirstFile(path.c_str(), &findFileData); if (fdHandle && (fdHandle != INVALID_HANDLE_VALUE)) { while (fdHandle) { path = fullpath; path += findFileData.cFileName; hLib = LoadLibrary(path.c_str()); if (hLib) { initializer = (TTExtensionInitializationMethod)GetProcAddress((HMODULE)hLib, "loadTTExtension"); if (initializer) err = initializer(); } if (!FindNextFile(fdHandle, &findFileData)) break; } } #else ; #endif }
void TTStringTestBasic(int& errorCount, int&testAssertionCount) { // TEST: empty string init TTTestLog("\n"); TTTestLog("Testing empty string assigment"); TTString empty; TTTestAssertion("created static const char* arg with correct size", empty.size() == 0, testAssertionCount, errorCount); TTTestAssertion("created from static const char* arg with correct length", empty.length() == 0, testAssertionCount, errorCount); TTTestAssertion("created from static const char* arg correctly null terminated", empty.at(0) == 0, testAssertionCount, errorCount); // TEST: c-string init TTTestLog("\n"); TTTestLog("Testing basic string assigment"); TTString foo("foo"); TTTestAssertion("created from static const char* arg with correct size", foo.size() == 3, testAssertionCount, errorCount); TTTestAssertion("created from static const char* arg with correct length", foo.length() == 3, testAssertionCount, errorCount); TTTestAssertion("created from static const char* arg with correct chars", foo.at(0) == 'f' && foo.at(1) == 'o' && foo.at(2) == 'o', testAssertionCount, errorCount); TTTestAssertion("created from static const char* arg correctly null terminated", foo.at(3) == 0, testAssertionCount, errorCount); // TEST: = init TTTestLog("\n"); TTTestLog("Testing = assigment"); TTString jet; jet = "jet"; TTTestAssertion("created from = with correct size", jet.size() == 3, testAssertionCount, errorCount); TTTestAssertion("created from = with correct length", jet.length() == 3, testAssertionCount, errorCount); TTTestAssertion("created from = with correct chars", jet.at(0) == 'j' && jet.at(1) == 'e' && jet.at(2) == 't', testAssertionCount, errorCount); TTTestAssertion("created from = correctly null terminated", jet.at(3) == 0, testAssertionCount, errorCount); // TEST: clear TTTestLog("\n"); TTTestLog("Testing clear method"); TTString nothing = "something"; nothing.clear(); TTTestAssertion("cleared string with correct size", empty.size() == 0, testAssertionCount, errorCount); TTTestAssertion("cleared string with correct length", empty.length() == 0, testAssertionCount, errorCount); TTTestAssertion("cleared string correctly null terminated", empty.at(0) == 0, testAssertionCount, errorCount); // TEST: individual char access TTTestLog("\n"); TTTestLog("Testing [] assigment"); foo[0] = 'g'; foo[2] = foo[2] + 1; TTTestAssertion("modified some chars using [] notation", foo.at(0) == 'g' && foo.at(1) == 'o' && foo.at(2) == 'p', testAssertionCount, errorCount); // TEST: comparison (depends on the result from above) TTTestLog("\n"); TTTestLog("Testing == operator"); TTString gop("gop"); TTString bar("bar"); TTString foobar("foobar"); TTTestAssertion("== operator when strings have the same content", foo == gop, testAssertionCount, errorCount); TTTestAssertion("== operator when strings have different content", !(foo == bar), testAssertionCount, errorCount); TTTestAssertion("!= operator when strings have the same content", !(foo != gop), testAssertionCount, errorCount); TTTestAssertion("!= operator when strings have different content", (foo != bar), testAssertionCount, errorCount); TTTestAssertion("== operator with c-string when strings have the same content", foo == "gop", testAssertionCount, errorCount); TTTestAssertion("== operator with c-string when strings have different content", !(foo == "bar"), testAssertionCount, errorCount); TTTestAssertion("!= operator with c-string when strings have the same content", !(foo != "gop"), testAssertionCount, errorCount); TTTestAssertion("!= operator with c-string when strings have different content", (foo != "bar"), testAssertionCount, errorCount); // here the length given to the substring is too long // so the foobar string is bar\00 after the substring // bu the last zero makes foobar different to bar foobar = foobar.substr(3, 4); TTTestAssertion("== operator with string when strings have the same content but one created using substr with an oversize length", bar == foobar, testAssertionCount, errorCount); }
void TTStringTestNumeric(int& errorCount, int&testAssertionCount) { TTTestLog("\n"); TTTestLog("Testing substring operation"); TTString series("0123456789"); TTString sub = series.substr(3,3); TTTestAssertion("created from substr with correct size", sub.size() == 3, testAssertionCount, errorCount); TTTestAssertion("created from substr with correct length", sub.length() == 3, testAssertionCount, errorCount); TTTestAssertion("created from substr with correct chars", sub.at(0) == '3' && sub.at(1) == '4' && sub.at(2) == '5', testAssertionCount, errorCount); TTTestAssertion("created from substr correctly null terminated", sub.at(3) == 0, testAssertionCount, errorCount); TTTestLog("\n"); TTTestLog("Testing summing operation"); TTString sumA; sumA += "/"; TTTestAssertion("created from += operator with correct size", sumA.size() == 1, testAssertionCount, errorCount); TTTestAssertion("created from += operator with correct length", sumA.length() == 1, testAssertionCount, errorCount); TTTestAssertion("created from += operator correctly null terminated", sumA.at(1) == 0, testAssertionCount, errorCount); TTString sumB; sumB += '/'; TTTestAssertion("created from += operator with correct size", sumB.size() == 1, testAssertionCount, errorCount); TTTestAssertion("created from += operator with correct length", sumB.length() == 1, testAssertionCount, errorCount); TTTestAssertion("created from += operator correctly null terminated", sumB.at(1) == 0, testAssertionCount, errorCount); // TEST: appending numbers TTTestLog("\n"); TTTestLog("Testing appending numbers"); TTString a; TTString b("Pi is roughly 7/22"); a += "Pi is roughly "; a += 7u; a += "/"; a += 22; TTTestAssertion("string built-up with a couple of ints in it", a == b, testAssertionCount, errorCount); b = "Pi is roughly 3.140000"; a = "Pi is roughly "; a += 3.14f; TTTestAssertion("string built-up with a float in it", a == b, testAssertionCount, errorCount); a = "Pi is roughly "; a += 3.14; TTTestAssertion("string built-up with a double in it", a == b, testAssertionCount, errorCount); TTTestLog("\n"); TTTestLog("Testing + operator"); TTString z("At the far end of town"); TTString y("where the grickle grass grows"); TTString x("and the wind smells sour as it blows"); TTString w = z + " " + y + " " + x + "..."; TTTestAssertion("string built-up with + operator", w == TTString("At the far end of town where the grickle grass grows and the wind smells sour as it blows..."), testAssertionCount, errorCount); }
TTErr TTSoundfile::test(TTValue& returnedTestInfo) { int errorCount = 0; int testAssertionCount = 0; // assemble the full path of the target sound file TTString testSoundPath = TTFoundationBinaryPath; int pos = testSoundPath.find_last_of('/'); testSoundPath = testSoundPath.substr(0,pos+1); testSoundPath += TESTFILE; std::cout << "We will be using the following path for testing: " << testSoundPath << "\n"; { TTTestLog("\n"); TTTestLog("Testing TTSoundfile Basics..."); // TEST 0: instantiate the object to a pointer // ** REMOVED ** // TEST 1: set the filepath TTBoolean result1 = { this->setFilePath(TT(testSoundPath)) == kTTErrNone }; TTTestAssertion("setFilePath operates successfully", result1, testAssertionCount, errorCount); // TEST 2: reports correct number of channels TTColumnID return2 = this->getNumChannels(); TTBoolean result2 = { return2 == TESTNUMCHANNELS }; TTTestAssertion("reports the correct number of channels", result2, testAssertionCount, errorCount); if(!result2) { TTTestLog("Expected a value of %i, but returned value was %i", TESTNUMCHANNELS, return2); } // TEST 3: reports correct sample rate TTFloat64 return3 = this->getSampleRate(); TTBoolean result3 = TTTestFloatEquivalence(return3, TESTSAMPLERATE, true, 0.0000001); TTTestAssertion("reports the correct sample rate", result3, testAssertionCount, errorCount); if(!result3) { TTTestLog("Expected a value of %f, but returned value was %f", TESTSAMPLERATE, return3); } // TEST 4: reports correct duration in samples TTRowID return4 = this->getLengthInSamples(); TTBoolean result4 = { return4 == TESTDURATIONINSAMPLES }; TTTestAssertion("reports the correct duration in samples", result4, testAssertionCount, errorCount); if(!result4) { TTTestLog("Expected a value of %i, but returned value was %i", TESTDURATIONINSAMPLES, return4); } // TEST 5: reports correct duration in seconds TTFloat64 return5 = this->getLengthInSeconds(); TTBoolean result5 = TTTestFloatEquivalence(return5, TESTDURATIONINSECONDS, true, 0.0000001); TTTestAssertion("reports the correct duration in seconds", result5, testAssertionCount, errorCount); if(!result5) { TTTestLog("Expected a value of %f, but returned value was %f", TESTDURATIONINSECONDS, return5); } TTTestLog("\n"); TTTestLog("Testing TTSoundfile Metadata..."); // TEST 6: reports correct title from metadata TTSymbol return6 = this->getTitle(); TTTestLog("Expected metadata title:"); TTTestLog(TESTTITLE); TTTestLog("Returned metadata title:"); TTTestLog(return6.c_str()); // TEST 7: reports correct artist from metadata TTSymbol return7 = this->getArtist(); TTTestLog("Expected metadata artist:"); TTTestLog(TESTARTIST); TTTestLog("Returned metadata artist:"); TTTestLog(return7.c_str()); // TEST 8: reports correct title from metadata TTSymbol return8 = this->getDate(); TTTestLog("Expected metadata date:"); TTTestLog(TESTDATE); TTTestLog("Returned metadata date:"); TTTestLog(return8.c_str()); // TEST 9: reports correct artist from metadata TTSymbol return9 = this->getAnnotation(); TTTestLog("Expected metadata comment:"); TTTestLog(TESTANNOTATION); TTTestLog("Returned metadata comment:"); TTTestLog(return9.c_str()); TTTestLog("\n"); TTTestLog("Testing peek method on first 10 sample values..."); TTSampleValue return10; TTErr error10; for (int channel=0;channel<return2;channel++) { TTTestLog("Channel %i", channel); for (int sample=0;sample<10;sample++) { error10 = this->peek(sample,channel,return10); if (error10 == kTTErrNone) { TTTestLog("peek sample %i returned the value %f", sample, return10); } else { TTTestLog("peek returned an error for sample %i", sample); } } } TTTestLog("\n"); TTTestLog("Testing peeki between samples 2 & 3..."); TTSampleValue return11; TTErr error11; TTFloat64 floatIndex; for (int channel=0;channel<return2;channel++) { TTTestLog("Channel %i", channel); for (int sample=0;sample<11;sample++) { floatIndex = 2 + sample*0.1; error11 = this->peeki(floatIndex,channel,return11); if (error11 == kTTErrNone) { TTTestLog("peek sample %f returned the value %f", floatIndex, return11); } else { TTTestLog("peek returned an error for sample %f", floatIndex); } } } } return TTTestFinish(testAssertionCount, errorCount, returnedTestInfo); }