Beispiel #1
0
    AudioWorld::AudioWorld(Engine::BaseEngine& engine, AudioEngine& audio_engine, const VDFS::FileIndex& vdfidx)
        : m_Engine(engine)
        , m_VDFSIndex(vdfidx)
        , m_exiting(false)
    {
#ifdef RE_USE_SOUND
        if (!audio_engine.getDevice())
            return;

        m_Context = alcCreateContext(audio_engine.getDevice(), nullptr);
        if (!m_Context)
        {
            LogWarn() << "Could not create OpenAL context: "
                      << AudioEngine::getErrorString(alcGetError(audio_engine.getDevice()));
            return;
        }

        alcMakeContextCurrent(m_Context);

        alListener3f(AL_POSITION, 0, 0, 0.0f);
        // check for errors
        alListener3f(AL_VELOCITY, 0, 0, 0);
        // check for errors
        ALfloat listenerOri[] = {0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f};
        alListenerfv(AL_ORIENTATION, listenerOri);

        // Need this for AL_MAX_DISTANCE to work
        alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);

        createSounds();

        initializeMusic();
#endif
    }
Beispiel #2
0
	int tick(void *outputBuffer, void *inputBuffer, U32 nBufferFrames,
			double streamTime, RtAudioStreamStatus status, void *userData)
	{
		if (status == 0)
        {
        	AudioEngine *engine = reinterpret_cast<AudioEngine *>(userData);
			engine->processChannels(outputBuffer, nBufferFrames * 8);
        }
		return 0;
	}
void AudioHandleImpl::enqueue(std::function<void(AudioEmitter& src)> f)
{
	size_t id = handleId;
	AudioEngine* engine = facade.engine.get();
	facade.enqueue([id, engine, f] () {
		for (auto& src: engine->getSources(id)) {
			f(*src);
		}
	});
}
	static int AudioEngine_PortAudioCallback(
		const void *inputBuffer
		,void *outputBuffer
		,unsigned long framesPerBuffer
		,const PaStreamCallbackTimeInfo* timeInfo
		,PaStreamCallbackFlags statusFlags
		,void *userData
	){
		AudioEngine* engine = (AudioEngine*) userData;
		return engine->fetchSoundData( outputBuffer, framesPerBuffer );
	}
Beispiel #5
0
    /**
     * Change pitch, pan and gain of a sound
     * Implementation of the setParams method in AudioPlayer.java
     */
    JNIEXPORT bool JNICALL Java_com_prettysimple_audio_AudioPlayer_setParams(JNIEnv *env, jobject thiz, jfloat pitch, jfloat pan, jfloat volume) {
        bool ret = false;
        AudioEngine *engine = AudioEngine::getInstance();

        const int audioId = getAudioId(env, thiz); // try to recover the audioIde from the AudioPlayer.java object

        if (audioId > 0)
        {
            ret = engine->setParams(audioId, (float) pitch, (float) pan, (float) volume);
        }
        return ret;
    }
Beispiel #6
0
void SoundNode::startDecoding()
{
    AudioEngine* pEngine = AudioEngine::get();
    m_pDecoder->startDecoding(false, pEngine->getParams());
    m_AudioID = pEngine->addSource(*m_pDecoder->getAudioMsgQ(), 
            *m_pDecoder->getAudioStatusQ());
    pEngine->setSourceVolume(m_AudioID, m_Volume);
    if (m_SeekBeforeCanRenderTime != 0) {
        seek(m_SeekBeforeCanRenderTime);
        m_SeekBeforeCanRenderTime = 0;
    }
}
/*! Read samples from the current audio device */
v8::Handle<v8::Value> Audio::AudioEngine::read( const v8::Arguments& args ) {
	HandleScope scope;

	AudioEngine* pEngine = AudioEngine::Unwrap<AudioEngine>( args.This() );

	if (pEngine->m_bReadMicrophone) {
		Pa_ReadStream( pEngine->m_pPaStream, pEngine->m_cachedInputSampleBlock, pEngine->m_uSamplesPerBuffer );
	}

	Handle<Array> input = pEngine->getInputBuffer();

	return scope.Close( input );
} // end AudioEngine::Read()
Beispiel #8
0
    /**
     * Resume a sound that has been paused
     * Implementation of the resume method in AudioPlayer.java
     */
    JNIEXPORT bool JNICALL Java_com_prettysimple_audio_AudioPlayer_resume(JNIEnv *env, jobject thiz)
    {
        bool ret = false;
        AudioEngine *engine = AudioEngine::getInstance();

        const int audioId = getAudioId(env, thiz);

        if (audioId > 0)
        {
            ret = engine->resume(audioId);
        }
        return ret;
    }
Beispiel #9
0
    /**
     * Pause a sound
     * Implementation of the pause method in AudioPlayer.java
     */
    JNIEXPORT bool JNICALL Java_com_prettysimple_audio_AudioPlayer_pause(JNIEnv *env, jobject thiz)
    {
        bool ret = false;
        AudioEngine *engine = AudioEngine::getInstance();

        const int audioId = getAudioId(env, thiz); // try to recover the audioIde from the AudioPlayer.java object

        if (audioId > 0)
        {
            ret = engine->pause(audioId);
        }
        return ret;
    }
/*! Our V8 new operator */
v8::Handle<v8::Value> Audio::AudioEngine::New( const v8::Arguments& args ) {
	HandleScope scope;

	if (!args[0]->IsFunction()) {
		return ThrowException( Exception::TypeError(String::New("Callback function required")) );
	}

	Local<Function> callback = Local<Function>::Cast( args[0] );
	
	AudioEngine* engine = new AudioEngine( callback );
	engine->Wrap( args.This() );

	return scope.Close( args.This() );
} // end AudioEngine::New()
/*! Write samples to the current audio device */
v8::Handle<v8::Value> Audio::AudioEngine::write( const v8::Arguments& args ) {
	HandleScope scope;

	AudioEngine* pEngine = AudioEngine::Unwrap<AudioEngine>( args.This() );

	if (args.Length() > 1 || !args[0]->IsArray()){
		return scope.Close( ThrowException(Exception::TypeError(String::New("First argument should be an array."))) );
	}

	uv_mutex_lock( &pEngine->m_mutex );
	pEngine->queueOutputBuffer( Local<Array>::Cast(args[0]) );
	uv_mutex_unlock( &pEngine->m_mutex );

	Handle<Boolean> result = Boolean::New( false );

	return scope.Close( result );
} // end AudioEngine::Write()
Beispiel #12
0
int main()
{
  ae.openAudio();
  cow();
  sine_2(4);

  sine_1(4);

}
/*! Create a v8 object */
v8::Handle<v8::Value> Audio::AudioEngine::New( const v8::Arguments& args ) {
	HandleScope scope;

	Local<Object> options;

	if( args.Length() > 0 ) {
		if( !args[0]->IsObject() )
			return scope.Close( ThrowException(Exception::TypeError(String::New("First argument must be an object."))) );
		else
			options = Local<Object>::Cast( args[0] );
	} else {
		options = Object::New();
	}

	AudioEngine* pEngine = new AudioEngine( options );
	pEngine->Wrap( args.This() );

	return scope.Close( args.This() );
} // end AudioEngine::New()
/*! Set options, restarts audio stream */
v8::Handle<v8::Value> Audio::AudioEngine::setOptions( const v8::Arguments& args ) {
	HandleScope scope;
	Local<Object> options;

	if( args.Length() > 0 ) {
		if( !args[0]->IsObject() ) {
			return scope.Close( ThrowException(Exception::TypeError(String::New("First argument should be an object."))) );
		}

		options = Local<Object>::Cast( args[0] );
	} else {
		return scope.Close( Exception::TypeError(String::New("First argument does not exist.")) );
	}

	AudioEngine* pEngine = AudioEngine::Unwrap<AudioEngine>( args.This() );
	pEngine->applyOptions( options );

	return scope.Close( Undefined() );
} // end AudioEngine::SetOptions()x
/*! Changes the output device */
v8::Handle<v8::Value> Audio::AudioEngine::SetOutputDevice( const v8::Arguments& args ) {
	HandleScope scope;

	// Validate the output args
	if( !args[0]->IsNumber() ) {
		return ThrowException( Exception::TypeError(String::New("setOutputDevice() requires a device index")) );
	}

	Local<Number> deviceIndex = Local<Number>::Cast( args[0] );

	AudioEngine* engine = AudioEngine::Unwrap<AudioEngine>( args.This() );

	// Set the new output device
	engine->m_outputParameters.device = deviceIndex->NumberValue();

	// Restart the audio stream
	engine->restartStream( engine );

	return scope.Close( Undefined() );
} // end AudioEngine::SetOutputDevice()
Beispiel #16
0
	bool AudioEngine::FillBuffer(void** data, int* dataSize, void* context){
		AudioEngine* engine = (AudioEngine*)context;
		return engine->fillBuffer(data, dataSize);
	}
Beispiel #17
0
void AudioEngine::audioCallback(void *userData, Uint8 *audioBuffer, int audioBufferLen)
{
    AudioEngine *pThis = (AudioEngine*)userData;
    pThis->mixAudio(audioBuffer, audioBufferLen);
}
Beispiel #18
0
int main(int argc, char *argv[])
{
	try {
		// Options...
		char *cp;
		struct option *op;
		char opts[NELEM(long_opts) * 3 + 1];

		// Build up the short option QString
		cp = opts;
		for (op = long_opts; op < &long_opts[NELEM(long_opts)]; op++) {
			*cp++ = op->val;
			if (op->has_arg)
				*cp++ = ':';
			if (op->has_arg == optional_argument )
				*cp++ = ':';  // gets another one
		}

		// Deal with the options
		QString songFilename;
		QString playlistFilename;
		QString outFilename = NULL;
		QString sSelectedDriver;
		bool showVersionOpt = false;
		const char* logLevelOpt = "Error";
		bool showHelpOpt = false;
		QString drumkitName;
		QString drumkitToLoad;
		short bits = 16;
		int rate = 44100;
		short interpolation = 0;
#ifdef H2CORE_HAVE_JACKSESSION
		QString sessionId;
#endif
		int c;
		while ( 1 ) {
			c = getopt_long(argc, argv, opts, long_opts, NULL);
			if ( c == -1 ) break;

			switch(c) {
			case 'd':
				sSelectedDriver = QString::fromLocal8Bit(optarg);
				break;
			case 's':
				songFilename = QString::fromLocal8Bit(optarg);
				break;
			case 'p':
				playlistFilename = QString::fromLocal8Bit(optarg);
				break;
			case 'o':
				outFilename = QString::fromLocal8Bit(optarg);
				break;
			case 'i':
				//install h2drumkit
				drumkitName = QString::fromLocal8Bit(optarg);
				break;
			case 'k':
				//load Drumkit
				drumkitToLoad = QString::fromLocal8Bit(optarg);
				break;
			case 'r':
				rate = strtol(optarg, NULL, 10);
				break;
			case 'b':
				bits = strtol(optarg, NULL, 10);
				break;
			case 'v':
				showVersionOpt = true;
				break;
			case 'V':
				logLevelOpt = (optarg) ? optarg : "Warning";
				break;
#ifdef H2CORE_HAVE_JACKSESSION
			case 'S':
				sessionId = QString::fromLocal8Bit(optarg);
				break;
#endif
			case 'h':
			case '?':
				showHelpOpt = true;
				break;
			}
		}

		if ( showVersionOpt ) {
			cout << get_version() << endl;
			exit(0);
		}

		showInfo();
		if ( showHelpOpt ) {
			showUsage();
			exit(0);
		}

		// Man your battle stations... this is not a drill.
		Logger* logger = Logger::bootstrap( Logger::parse_log_level( logLevelOpt ) );
		Object::bootstrap( logger, logger->should_log( Logger::Debug ) );
		Filesystem::bootstrap( logger );
		MidiMap::create_instance();
		Preferences::create_instance();
		Preferences* preferences = Preferences::get_instance();
		// See below for Hydrogen.

		___INFOLOG( QString("Using QT version ") + QString( qVersion() ) );
		___INFOLOG( "Using data path: " + Filesystem::sys_data_path() );

#ifdef H2CORE_HAVE_LASH
		LashClient::create_instance("hydrogen", "Hydrogen", &argc, &argv);
		LashClient* lashClient = LashClient::get_instance();
#endif

		if ( ! drumkitName.isEmpty() ){
			Drumkit::install( drumkitName );
			exit(0);
		}

		if (sSelectedDriver == "auto") {
			preferences->m_sAudioDriver = "Auto";
		}
		else if (sSelectedDriver == "jack") {
			preferences->m_sAudioDriver = "Jack";
		}
		else if ( sSelectedDriver == "oss" ) {
			preferences->m_sAudioDriver = "Oss";
		}
		else if ( sSelectedDriver == "alsa" ) {
			preferences->m_sAudioDriver = "Alsa";
		}
		else if (sSelectedDriver == "CoreAudio") {
			preferences->m_sAudioDriver = "CoreAudio";
		}
		else if (sSelectedDriver == "PulseAudio") {
			preferences->m_sAudioDriver = "PulseAudio";
		}

#ifdef H2CORE_HAVE_LASH
		if ( preferences->useLash() && lashClient->isConnected() ) {
			lash_event_t* lash_event = lashClient->getNextEvent();
			if (lash_event && lash_event_get_type(lash_event) == LASH_Restore_File) {
				// notify client that this project was not a new one
				lashClient->setNewProject(false);

				songFilename = "";
				songFilename.append( QString::fromLocal8Bit(lash_event_get_string(lash_event)) );
				songFilename.append("/hydrogen.h2song");

				//Logger::get_instance()->log("[LASH] Restore file: " + songFilename);

				lash_event_destroy(lash_event);
			} else if (lash_event) {
				//Logger::get_instance()->log("[LASH] ERROR: Instead of restore file got event: " + lash_event_get_type(lash_event));
				lash_event_destroy(lash_event);
			}
		}
#endif
#ifdef H2CORE_HAVE_JACKSESSION
		if (!sessionId.isEmpty()) {
			preferences->setJackSessionUUID ( sessionId );
			/* imo, jack sessions use jack as default audio driver.
			 * hydrogen remember last used audiodriver.
			 * here we make it save that hydrogen start in a jacksession case
			 * every time with jack as audio driver
			 */
			preferences->m_sAudioDriver = "Jack";

		}
		/* the use of applicationFilePath() make it
		 * possible to use different executables.
		 * for example if you start hydrogen from a local
		 * build directory.
		 */
//		QString path = pQApp->applicationFilePath();
//		preferences->setJackSessionApplicationPath ( path );
#endif
		Hydrogen::create_instance();
		Hydrogen *pHydrogen = Hydrogen::get_instance();
		Song *pSong = NULL;
		Playlist *pPlaylist = NULL;

		// Load playlist
		if ( ! playlistFilename.isEmpty() ) {
			pPlaylist = Playlist::load ( playlistFilename );
			if ( ! pPlaylist ) {
				___ERRORLOG( "Error loading the playlist" );
				return 0;
			}

			/* Load first song */
			preferences->setLastPlaylistFilename( playlistFilename );
			pPlaylist->loadSong( 0 );
			pSong = pHydrogen->getSong();
			show_playlist ( pHydrogen, pPlaylist->getActiveSongNumber() );
		}

		// Load song - if wasn't already loaded with playlist
		if ( ! pSong ) {
			if ( !songFilename.isEmpty() ) {
				pSong = Song::load( songFilename );
			} else {
				/* Try load last song */
				bool restoreLastSong = preferences->isRestoreLastSongEnabled();
				QString filename = preferences->getLastSongFilename();
				if ( restoreLastSong && ( !filename.isEmpty() ))
					pSong = Song::load( filename );
			}

			/* Still not loaded */
			if (! pSong) {
				___INFOLOG("Starting with empty song");
				pSong = Song::get_empty_song();
				pSong->set_filename( "" );
			}

			pHydrogen->setSong( pSong );
			preferences->setLastSongFilename( songFilename );
		}

		if ( ! drumkitToLoad.isEmpty() ){
			Drumkit* drumkitInfo = Drumkit::load_by_name( drumkitToLoad, true );
			if ( drumkitInfo ) {
				pHydrogen->loadDrumkit( drumkitInfo );
			} else {
				___ERRORLOG ( "Error loading the drumkit" );
			}
		}

		AudioEngine* AudioEngine = AudioEngine::get_instance();
		Sampler* sampler = AudioEngine->get_sampler();
		switch ( interpolation ) {
			case 1:
					sampler->setInterpolateMode( Sampler::COSINE );
					break;
			case 2:
					sampler->setInterpolateMode( Sampler::THIRD );
					break;
			case 3:
					sampler->setInterpolateMode( Sampler::CUBIC );
					break;
			case 4:
					sampler->setInterpolateMode( Sampler::HERMITE );
					break;
			case 0:
			default:
					sampler->setInterpolateMode( Sampler::LINEAR );
		}

		EventQueue *pQueue = EventQueue::get_instance();

		signal(SIGINT, signal_handler);

		bool ExportMode = false;
		if ( ! outFilename.isEmpty() ) {
			pHydrogen->startExportSong ( outFilename, rate, bits );
			cout << "Export Progress ... ";
			bool ExportMode = true;
		}

		// Interactive mode
		while ( ! quit ) {
			/* FIXME: Someday here will be The Real CLI ;-) */
			Event event = pQueue->pop_event();
			// if ( event.type > 0) cout << "EVENT TYPE: " << event.type << endl;

			/* Event handler */
			switch ( event.type ) {
			case EVENT_PROGRESS: /* event used only in export mode */
				if ( ! ExportMode ) break;
	
				if ( event.value < 100 ) {
					cout << "\rExport Progress ... " << event.value << "%";
				} else {
					cout << "\rExport Progress ... DONE" << endl;
					quit = true;
				}
				break;
			case EVENT_PLAYLIST_LOADSONG: /* Load new song on MIDI event */
				if ( pPlaylist->loadSong ( event.value ) ) {
					pSong = pHydrogen->getSong();
					show_playlist ( pHydrogen, pPlaylist->getActiveSongNumber() );
				}
				break;
			case EVENT_NONE: /* Sleep if there is no more events */
				Sleeper::msleep ( 100 );
				break;
			}
		}

		if ( pHydrogen->getState() == STATE_PLAYING )
			pHydrogen->sequencer_stop();

		delete pSong;
		delete pPlaylist;

		delete pQueue;
		delete pHydrogen;
		delete preferences;
		delete AudioEngine;

		delete MidiMap::get_instance();
		delete MidiActionManager::get_instance();

		___INFOLOG( "Quitting..." );
		delete Logger::get_instance();

		int nObj = Object::objects_count();
		if (nObj != 0) {
			cerr << "\n\n\n " << nObj << " alive objects\n\n" << endl << endl;
			Object::write_objects_map_to_cerr();
		}
	}
	catch ( const H2Exception& ex ) {
		cerr << "[main] Exception: " << ex.what() << endl;
	}
	catch (...) {
		cerr << "[main] Unknown exception X-(" << endl;
	}

	return 0;
}
Beispiel #19
0
void AudioEngine::bq_player_callback(SLAndroidSimpleBufferQueueItf bq, void* data)
{
  AudioEngine* engine = static_cast<AudioEngine*> (data);
  engine->bq_player_callback_handler(bq);
}