PRO_API
pro_error pro_library_load(pro_state_ref s, const char* file)
{
    if (pro_library_loaded(s, file) != 0)
        return PRO_OK;
    
    void* handle = dlopen(file, RTLD_LOCAL | RTLD_LAZY);
    if (handle)
    {
        initialize_library(s, handle);
        add_loaded_library(s, file, handle);
    }
    else
        return PRO_LIBRARY_LOAD_ERROR;
    
    return PRO_OK;
}
Beispiel #2
0
World* World_New(WorldOptions *inOptions)
{
#if (_POSIX_MEMLOCK - 0) >=  200112L
	if (inOptions->mMemoryLocking && inOptions->mRealTime)
	{
		bool lock_memory = false;

		rlimit limit;

		int failure = getrlimit(RLIMIT_MEMLOCK, &limit);
		if (failure)
			scprintf("getrlimit failure\n");
		else
		{
			if (limit.rlim_cur == RLIM_INFINITY and
				limit.rlim_max == RLIM_INFINITY)
				lock_memory = true;
			else
				scprintf("memory locking disabled due to resource limiting\n");

			if (lock_memory)
			{
				if (mlockall(MCL_FUTURE) != -1)
					scprintf("memory locking enabled.\n");
			}
		}
	}
#endif

	World *world = 0;

	try {
		static bool gLibInitted = false;
		if (!gLibInitted) {
			InterfaceTable_Init();
			initialize_library(inOptions->mUGensPluginPath);
			initializeScheduler();
			gLibInitted = true;
		}

		world = (World*)zalloc(1, sizeof(World));

		world->hw = (HiddenWorld*)zalloc(1, sizeof(HiddenWorld));

		world->hw->mAllocPool = new AllocPool(malloc, free, inOptions->mRealTimeMemorySize * 1024, 0);
		world->hw->mQuitProgram = new boost::sync::semaphore(0);
		world->hw->mTerminating = false;

		HiddenWorld *hw = world->hw;
		hw->mGraphDefLib = new HashTable<struct GraphDef, Malloc>(&gMalloc, inOptions->mMaxGraphDefs, false);
		hw->mNodeLib = new IntHashTable<Node, AllocPool>(hw->mAllocPool, inOptions->mMaxNodes, false);
		hw->mUsers = new Clients();
		hw->mMaxUsers = inOptions->mMaxLogins;
		hw->mAvailableClientIDs = new ClientIDs();
		for (int i = 0; i<hw->mMaxUsers; i++) {
			hw->mAvailableClientIDs->push_back(i);
		}
		hw->mClientIDdict = new ClientIDDict();
		hw->mHiddenID = -8;
		hw->mRecentID = -8;


		world->mNumUnits = 0;
		world->mNumGraphs = 0;
		world->mNumGroups = 0;

		world->mBufCounter = 0;
		world->mBufLength = inOptions->mBufLength;
		world->mSampleOffset = 0;
		world->mSubsampleOffset = 0.f;
		world->mNumAudioBusChannels = inOptions->mNumAudioBusChannels;
		world->mNumControlBusChannels = inOptions->mNumControlBusChannels;
		world->mNumInputs = inOptions->mNumInputBusChannels;
		world->mNumOutputs = inOptions->mNumOutputBusChannels;

		world->mVerbosity = inOptions->mVerbosity;
		world->mErrorNotification = 1;  // i.e., 0x01 | 0x02
		world->mLocalErrorNotification = 0;

		if (inOptions->mSharedMemoryID) {
			server_shared_memory_creator::cleanup(inOptions->mSharedMemoryID);
			hw->mShmem = new server_shared_memory_creator(inOptions->mSharedMemoryID, inOptions->mNumControlBusChannels);
			world->mControlBus = hw->mShmem->get_control_busses();
		} else {
			hw->mShmem = 0;
			world->mControlBus = (float*)zalloc(world->mNumControlBusChannels, sizeof(float));
		}

		world->mNumSharedControls = 0;
		world->mSharedControls = inOptions->mSharedControls;

		int numsamples = world->mBufLength * world->mNumAudioBusChannels;
		world->mAudioBus = (float*)zalloc(numsamples, sizeof(float));

		world->mAudioBusTouched = (int32*)zalloc(inOptions->mNumAudioBusChannels, sizeof(int32));
		world->mControlBusTouched = (int32*)zalloc(inOptions->mNumControlBusChannels, sizeof(int32));

		world->mNumSndBufs = inOptions->mNumBuffers;
		world->mSndBufs = (SndBuf*)zalloc(world->mNumSndBufs, sizeof(SndBuf));
		world->mSndBufsNonRealTimeMirror = (SndBuf*)zalloc(world->mNumSndBufs, sizeof(SndBuf));
		world->mSndBufUpdates = (SndBufUpdates*)zalloc(world->mNumSndBufs, sizeof(SndBufUpdates));

		GroupNodeDef_Init();

		int err = Group_New(world, 0, &world->mTopGroup);
		if (err) throw err;

		world->mRealTime = inOptions->mRealTime;

		world->ft = &gInterfaceTable;

		world->mNumRGens = inOptions->mNumRGens;
		world->mRGen = new RGen[world->mNumRGens];
		for (uint32 i=0; i<world->mNumRGens; ++i) {
			world->mRGen[i].init(server_timeseed());
		}

		world->mNRTLock = new SC_Lock();
		world->mDriverLock = new SC_Lock();

		if (inOptions->mPassword) {
			strncpy(world->hw->mPassword, inOptions->mPassword, 31);
			world->hw->mPassword[31] = 0;
		} else {
			world->hw->mPassword[0] = 0;
		}

#ifdef __APPLE__
		world->hw->mInputStreamsEnabled = inOptions->mInputStreamsEnabled;
		world->hw->mOutputStreamsEnabled = inOptions->mOutputStreamsEnabled;
#endif
		world->hw->mInDeviceName = inOptions->mInDeviceName;
		world->hw->mOutDeviceName = inOptions->mOutDeviceName;
		hw->mMaxWireBufs = inOptions->mMaxWireBufs;
		hw->mWireBufSpace = 0;

		world->mRendezvous = inOptions->mRendezvous;

		world->mRestrictedPath = inOptions->mRestrictedPath;

		sc_SetDenormalFlags();

		if (world->mRealTime) {
			hw->mAudioDriver = SC_NewAudioDriver(world);
			hw->mAudioDriver->SetPreferredHardwareBufferFrameSize(
					inOptions->mPreferredHardwareBufferFrameSize
			);
			hw->mAudioDriver->SetPreferredSampleRate(
					inOptions->mPreferredSampleRate
			);

			if (inOptions->mLoadGraphDefs) {
				World_LoadGraphDefs(world);
			}

			if (!hw->mAudioDriver->Setup()) {
				scprintf("could not initialize audio.\n");
				return 0;
			}
			if (!hw->mAudioDriver->Start()) {
				scprintf("start audio failed.\n");
				return 0;
			}

#ifdef __APPLE__
			SC::Apple::disableAppNap();
#endif


		} else {
			hw->mAudioDriver = 0;
		}

		if (!scsynth::asioThreadStarted()){
			scsynth::startAsioThread();
		}

	} catch (std::exception& exc) {
		scprintf("Exception in World_New: %s\n", exc.what());
		World_Cleanup(world,true);
		return 0;
	} catch (...) {
	}
	return world;
}