Lav_PUBLIC_FUNCTION LavError Lav_nodeGetOutputConnectionCount(LavHandle nodeHandle, unsigned int* destination) { PUB_BEGIN auto node = incomingObject<Node>(nodeHandle); LOCK(*node); *destination = node->getOutputConnectionCount(); PUB_END }
Lav_PUBLIC_FUNCTION LavError Lav_nodeReset(LavHandle nodeHandle) { PUB_BEGIN auto node = incomingObject<Node>(nodeHandle); LOCK(*node); node->reset(); PUB_END }
//callback setup/configure/retrieval. Lav_PUBLIC_FUNCTION LavError Lav_nodeGetEventHandler(LavHandle nodeHandle, int event, LavEventCallback *destination) { PUB_BEGIN auto ptr = incomingObject<Node>(nodeHandle); LOCK(*ptr); *destination = ptr->getEvent(event).getExternalHandler(); PUB_END }
Lav_PUBLIC_FUNCTION LavError Lav_nodeDisconnect(LavHandle nodeHandle, int output) { PUB_BEGIN auto node = incomingObject<Node>(nodeHandle); LOCK(*node); node->disconnect(output); PUB_END }
Lav_PUBLIC_FUNCTION LavError Lav_simulationWriteFile(LavHandle simulationHandle, const char* path, int channels, double duration, int mayApplyMixingMatrix) { PUB_BEGIN auto sim = incomingObject<Simulation>(simulationHandle); LOCK(*sim); sim->writeFile(path, channels, duration, mayApplyMixingMatrix); PUB_END }
Lav_PUBLIC_FUNCTION LavError Lav_simulationGetThreads(LavHandle simulationHandle, int* destination) { PUB_BEGIN auto sim = incomingObject<Simulation>(simulationHandle); LOCK(*sim); *destination = sim->getThreads(); PUB_END }
Lav_PUBLIC_FUNCTION LavError Lav_simulationClearOutputDevice(LavHandle simulationHandle) { PUB_BEGIN auto sim = incomingObject<Simulation>(simulationHandle); LOCK(*sim); sim->clearOutputDevice(); PUB_END }
Lav_PUBLIC_FUNCTION LavError Lav_simulationSetOutputDevice(LavHandle simulationHandle, int index, int channels, float minLatency, float startLatency, float maxLatency) { PUB_BEGIN auto sim = incomingObject<Simulation>(simulationHandle); //This is threadsafe and needs to be entered properly so it can make sure we dont' edadlock in audio_io. sim->setOutputDevice(index, channels, minLatency, startLatency, maxLatency); PUB_END }
Lav_PUBLIC_FUNCTION LavError Lav_simulationGetSr(LavHandle simulationHandle, int* destination) { PUB_BEGIN auto simulation =incomingObject<Simulation>(simulationHandle); LOCK(*simulation); *destination = (int)simulation->getSr(); PUB_END }
Lav_PUBLIC_FUNCTION LavError Lav_simulationGetBlock(LavHandle simulationHandle, unsigned int channels, int mayApplyMixingMatrix, float* destination) { PUB_BEGIN auto simulation = incomingObject<Simulation>(simulationHandle); LOCK(*simulation); simulation->getBlock(destination, channels, mayApplyMixingMatrix != 0); PUB_END }
Lav_PUBLIC_FUNCTION LavError Lav_createSimulation(unsigned int sr, unsigned int blockSize, LavHandle* destination) { PUB_BEGIN auto shared = std::make_shared<Simulation>(sr, blockSize, 0); shared->completeInitialization(); *destination = outgoingObject(shared); PUB_END }
Lav_PUBLIC_FUNCTION LavError Lav_nodeConnectProperty(LavHandle nodeHandle, int output, LavHandle otherHandle, int slot) { PUB_BEGIN auto n = incomingObject<Node>(nodeHandle); auto o = incomingObject<Node>(otherHandle); LOCK(*n); n->connectProperty(output, o, slot); PUB_END }
Lav_PUBLIC_FUNCTION LavError Lav_nodeConnect(LavHandle nodeHandle, int output, LavHandle destHandle, int input) { PUB_BEGIN auto node= incomingObject<Node>(nodeHandle); auto dest = incomingObject<Node>(destHandle); LOCK(*node); node->connect(output, dest, input); PUB_END }
Lav_PUBLIC_FUNCTION LavError Lav_nodeGetPropertyHasDynamicRange(LavHandle nodeHandle, int slot, int* destination) { PUB_BEGIN auto node = incomingObject<Node>(nodeHandle); LOCK(*node); auto &prop = node->getProperty(slot); *destination = prop.getHasDynamicRange(); PUB_END }
Lav_PUBLIC_FUNCTION LavError Lav_bufferNormalize(LavHandle bufferHandle) { PUB_BEGIN auto b = incomingObject<Buffer>(bufferHandle); LOCK(*b); b->throwIfInUse(); b->normalize(); PUB_END }
Lav_PUBLIC_FUNCTION LavError Lav_environmentNodePlayAsync(LavHandle nodeHandle, LavHandle bufferHandle, float x, float y, float z) { PUB_BEGIN auto e = incomingObject<EnvironmentNode>(nodeHandle); auto b = incomingObject<Buffer>(bufferHandle); LOCK(*e); e->playAsync(b, x, y, z); PUB_END }
Lav_PUBLIC_FUNCTION LavError Lav_bufferLoadFromArray(LavHandle bufferHandle, int sr, int channels, int frames, float* data) { PUB_BEGIN auto buff=incomingObject<Buffer>(bufferHandle); LOCK(*buff); buff->throwIfInUse(); buff->loadFromArray(sr, channels, frames, data); PUB_END }
Lav_PUBLIC_FUNCTION LavError Lav_pushNodeFeed(LavHandle nodeHandle, unsigned int length, float* buffer) { PUB_BEGIN auto node=incomingObject<Node>(nodeHandle); LOCK(*node); if(node->getType() != Lav_OBJTYPE_PUSH_NODE) ERROR(Lav_ERROR_TYPE_MISMATCH, "Expected a push node."); std::static_pointer_cast<PushNode>(node)->feed(length, buffer); PUB_END }
Lav_PUBLIC_FUNCTION LavError Lav_createPannerBankNode(LavHandle simulationHandle, int pannerCount, char* hrtfPath, LavHandle* destination) { PUB_BEGIN auto simulation = incomingObject<Simulation>(simulationHandle); LOCK(*simulation); auto hrtf = createHrtfFromString(hrtfPath, simulation->getSr()); *destination = outgoingObject<Node>(createPannerBankNode(simulation, pannerCount, hrtf)); PUB_END }
Lav_PUBLIC_FUNCTION LavError Lav_iirNodeSetCoefficients(LavHandle nodeHandle, int numeratorLength, double* numerator, int denominatorLength, double* denominator, int shouldClearHistory) { PUB_BEGIN auto node = incomingObject<Node>(nodeHandle); LOCK(*node); if(node->getType() != Lav_OBJTYPE_IIR_NODE) ERROR(Lav_ERROR_TYPE_MISMATCH, "Expected an IIR node."); std::static_pointer_cast<IirNode>(node)->setCoefficients(numeratorLength, numerator, denominatorLength, denominator, shouldClearHistory); PUB_END }
Lav_PUBLIC_FUNCTION LavError Lav_createHrtfNode(LavHandle simulationHandle, const char* hrtfPath, LavHandle* destination) { PUB_BEGIN auto simulation = incomingObject<Simulation>(simulationHandle); LOCK(*simulation); auto hrtf = createHrtfFromString(hrtfPath, simulation->getSr()); auto retval = createHrtfNode(simulation, hrtf); *destination = outgoingObject<Node>(retval); PUB_END }
Lav_PUBLIC_FUNCTION LavError Lav_nodeGetArrayPropertyLengthRange(LavHandle nodeHandle, int slot, unsigned int* destinationMin, unsigned int* destinationMax) { PUB_BEGIN auto ptr = incomingObject<Node>(nodeHandle); LOCK(*ptr); auto &prop = ptr->getProperty(slot); int type = prop.getType(); if(type != Lav_PROPERTYTYPE_FLOAT_ARRAY || type != Lav_PROPERTYTYPE_INT_ARRAY) ERROR(Lav_ERROR_TYPE_MISMATCH, "Property is not an array."); PUB_END }
Lav_PUBLIC_FUNCTION LavError Lav_nodeResetProperty(LavHandle nodeHandle, int slot) { PUB_BEGIN auto node_ptr = incomingObject<Node>(nodeHandle); LOCK(*node_ptr); auto prop = node_ptr->getProperty(slot); READONLY_CHECK prop.reset(); PUB_END }
Lav_PUBLIC_FUNCTION LavError Lav_pullNodeSetAudioCallback(LavHandle nodeHandle, LavPullNodeAudioCallback callback, void* userdata) { PUB_BEGIN auto node = incomingObject<Node>(nodeHandle); LOCK(*node); if(node->getType() != Lav_OBJTYPE_PULL_NODE) ERROR(Lav_ERROR_TYPE_MISMATCH, "Expected a pull node."); auto p = std::static_pointer_cast<PullNode>(node); p->callback = callback; p->callback_userdata = userdata; PUB_END }
Lav_PUBLIC_FUNCTION LavError Lav_automationLinearRampToValue(LavHandle nodeHandle, int slot, double time, double value) { PUB_BEGIN auto node = incomingObject<Node>(nodeHandle); LOCK(*node); auto &prop= node->getProperty(slot); LinearRampAutomator* automator = new LinearRampAutomator(&prop, prop.getTime()+time, value); //the property will throw for us if any part of the next part goes wrong. prop.scheduleAutomator(automator); PUB_END }
Lav_PUBLIC_FUNCTION LavError Lav_bufferTimelineNodeScheduleBuffer(LavHandle nodeHandle, LavHandle bufferHandle, double time, float pitchBend) { PUB_BEGIN auto n = incomingObject<BufferTimelineNode>(nodeHandle); auto b = incomingObject<Buffer>(bufferHandle); if(n->getType() !=Lav_OBJTYPE_BUFFER_TIMELINE_NODE || b->getType() !=Lav_OBJTYPE_BUFFER) ERROR(Lav_ERROR_TYPE_MISMATCH); if(time < 0.0) ERROR(Lav_ERROR_RANGE); if(pitchBend <0.0) ERROR(Lav_ERROR_RANGE); LOCK(*n); n->scheduleBuffer(time, pitchBend, b); PUB_END }
Lav_PUBLIC_FUNCTION LavError Lav_deviceGetName(unsigned int index, char** destination) { PUB_BEGIN auto n = (*audio_output_factory)->getOutputNames(); if(index >= n.size()) ERROR(Lav_ERROR_RANGE, "Invalid device index."); auto s = n[index]; char* outgoingStr = new char[s.size()+1]; std::copy(s.c_str(), s.c_str()+s.size(), outgoingStr); outgoingStr[s.size()] = '\0'; std::shared_ptr<char> outgoing(outgoingStr, [](char* what){delete[] what;}); *destination = outgoingPointer<char>(outgoing); PUB_END }
Lav_PUBLIC_FUNCTION LavError Lav_nodeGetPropertyName(LavHandle nodeHandle, int slot, char** destination) { PUB_BEGIN auto node_ptr = incomingObject<Node>(nodeHandle); LOCK(*node_ptr); auto prop = node_ptr->getProperty(slot); const char* n = prop.getName(); char* dest = new char[strlen(n)+1]; //+1 for extra NULL. strcpy(dest, n); *destination = outgoingPointer<char>(std::shared_ptr<char>(dest, [](char* ptr) {delete[] ptr;})); PUB_END }
Lav_PUBLIC_FUNCTION LavError Lav_createEnvironmentNode(LavHandle simulationHandle, const char*hrtfPath, LavHandle* destination) { PUB_BEGIN auto simulation = incomingObject<Simulation>(simulationHandle); LOCK(*simulation); auto hrtf = std::make_shared<HrtfData>(); if(std::string(hrtfPath) != "default") { hrtf->loadFromFile(hrtfPath, simulation->getSr()); } else { hrtf->loadFromDefault(simulation->getSr()); } auto retval = createEnvironmentNode(simulation, hrtf); *destination = outgoingObject<Node>(retval); PUB_END }
Lav_PUBLIC_FUNCTION LavError Lav_bufferLoadFromFile(LavHandle bufferHandle, const char* path) { PUB_BEGIN auto buff =incomingObject<Buffer>(bufferHandle); FileReader f{}; f.open(path); float* data = allocArray<float>(f.getSampleCount()); f.readAll(data); { LOCK(*buff); buff->throwIfInUse(); buff->loadFromArray(f.getSr(), f.getChannelCount(), f.getSampleCount()/f.getChannelCount(), data); } freeArray(data); PUB_END }