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 }
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 ); }
/** * 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; }
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()
/** * 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; }
/** * 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()
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()
bool AudioEngine::FillBuffer(void** data, int* dataSize, void* context){ AudioEngine* engine = (AudioEngine*)context; return engine->fillBuffer(data, dataSize); }
void AudioEngine::audioCallback(void *userData, Uint8 *audioBuffer, int audioBufferLen) { AudioEngine *pThis = (AudioEngine*)userData; pThis->mixAudio(audioBuffer, audioBufferLen); }
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; }
void AudioEngine::bq_player_callback(SLAndroidSimpleBufferQueueItf bq, void* data) { AudioEngine* engine = static_cast<AudioEngine*> (data); engine->bq_player_callback_handler(bq); }