예제 #1
0
void audiosource_alsa::loop_async_thread_play() {
	config* cfg = config::Instance();
	std::vector<short> buffer;
	std::vector<float> bufferf;
	snd_pcm_sframes_t frames;
	int ret;
	int buf_size = (cfg->frames_per_buff() > 0) ? cfg->frames_per_buff() : (get_sample_rate());
	bool restart = true;

	buffer.resize(buf_size);
	bufferf.resize(buf_size);

	if ((ret = snd_pcm_prepare(p_handle_)) < 0) {
		std::cerr << "snd_pcm_prepare playback error: " << snd_strerror(ret) << std::endl;
		close();
		return;
	}

	/* FIXME Break the loop */

	for (;;) {
		if (restart) {
			if (cfg->debug()) {
				std::cerr << "ALSA restart" << std::endl;
			}
			restart = false;
			snd_pcm_drop(c_handle_);
			snd_pcm_prepare(c_handle_);
		}

		/*
		for (size_t i = 0 ; i < bufferf.size(); ++i) {
			bufferf[i] = 0;
		}
		*/

		/* Write data to the soundcard */
		get_listener()->output_callback(this, bufferf.data(), bufferf.size());

		for (size_t i = 0 ; i < bufferf.size(); ++i) {
			buffer[i] = static_cast<short>( bufferf[i] * 32767 );
		}

		for (;;) {
			frames = snd_pcm_writei(p_handle_, buffer.data(), buffer.size());
			if (frames == -EAGAIN) {
				if (cfg->debug()) {
					std::cerr << "ALSA EAGAIN" << std::endl;
				}
				continue;
			} else {
				if (frames < 0) {
					if (cfg->debug()) {
						std::cerr << "ALSA snd_pcm_readi < 0 = " << frames << std::endl;
					}
					restart = true;
				}
				break;
			}
		}

		if (restart) {
			continue;
		}

		if (frames != (snd_pcm_sframes_t)buffer.size()) {
			if (cfg->debug()) {
				std::cerr << "ALSA short write, expected " << buffer.size() << " wrote " << frames << std::endl;
			}
		}
	}

	close();
}
예제 #2
0
dmz::Boolean
dmz::AudioModuleFMOD::destroy_listener (const Handle ListenerHandle) {

   Boolean result (False);
   if (_system) {

      ListenerStruct *listener = _listenerHandleTable.lookup (ListenerHandle);

      if (listener) {

         Int32 numListeners = _listenerHandleTable.get_count ();

         if (listener->index == (numListeners - 1)) {

            // Can simply reduce listener count in FMOD without rearranging indices

            FMOD_RESULT fmodResult (FMOD_OK);
            Boolean muteSuccess (True);

            // FMOD requires at least one listener
            if (numListeners > 1) {

               fmodResult = _system->set3DNumListeners (numListeners - 1);
            }
            else {

               // To simulate a lack of any listeners, mute all sounds
               muteSuccess = set_mute_all_state (True);
            }

            if (_error_check ("Destroying a Listener", fmodResult) && muteSuccess) {

               // Delete the listener
               _listenerHandleTable.remove (ListenerHandle);
               _listenerNameTable.remove (listener->Name);
               _listenerIndexTable.remove (listener->index);
               delete listener; listener = 0;
               result = True;
            }
         }
         else {
            // FMOD only allows the adjustment of the total number of listeners, so
            // we must swap the listener to be deleted with the last listener and
            // then reduce the total number of listeners in FMOD

            // Get last listener
            ListenerStruct *lastListener = _listenerIndexTable.lookup (numListeners - 1);

            if (lastListener) {

               // Get the position and orientation of listener to be moved
               Vector copiedPosition;
               Matrix copiedOrientation;
               Vector copiedVelocity;

               if (get_listener (
                     listener->get_handle (),
                     copiedPosition,
                     copiedOrientation,
                     copiedVelocity)) {

                  // Change the FMOD listener index to the index of the listener to be
                  // deleted
                  lastListener->index = listener->index;

                  // Override the listener attributes in the index location of the deleted
                  // listener
                  if (set_listener (
                     lastListener->get_handle (),
                     copiedPosition,
                     copiedOrientation,
                     copiedVelocity)) {

                     // Reduce reduce listener count in FMOD to erase the old data
                     // of the now duplicated listener at the end.
                     FMOD_RESULT fmodResult (
                        _system->set3DNumListeners (numListeners - 1));

                     if (_error_check ("Destroying a Listener", fmodResult)) {

                        // Delete the listener
                        _listenerHandleTable.remove (ListenerHandle);
                        _listenerNameTable.remove (listener->Name);
                        _listenerIndexTable.remove (listener->index);
                        delete listener; listener = 0;
                        result = True;
                     }
                  }
               }
            }
         }
      }
   }

   return result;
}
예제 #3
0
void audiosource_alsa::loop_async_thread_rec() {
	config* cfg = config::Instance();
	std::vector<short> buffer;
	std::vector<float> bufferf;
	snd_pcm_sframes_t frames;
	int ret;
	int buf_size = (cfg->frames_per_buff() > 0) ? cfg->frames_per_buff() : (get_sample_rate());
	bool restart = true;

	buffer.resize(buf_size);
	bufferf.resize(buf_size);

	if ((ret = snd_pcm_prepare(c_handle_)) < 0) {
		std::cerr << "snd_pcm_prepare capture error: " << snd_strerror(ret) << std::endl;
		close();
		return;
	}

	/* FIXME Break the loop */

	for (;;) {
		if (restart) {
			if (cfg->debug()) {
				std::cerr << "ALSA restart" << std::endl;
			}
			restart = false;
			snd_pcm_drop(c_handle_);
			snd_pcm_prepare(c_handle_);
		}

		/* Read data from the soundcard */
		for (;;) {
			frames = snd_pcm_readi(c_handle_, buffer.data(), buffer.size());
			if (frames == -EAGAIN) {
				if (cfg->debug()) {
					std::cerr << "ALSA EAGAIN" << std::endl;
				}
				continue;
			} else {
				if (frames < 0) {
					if (cfg->debug()) {
						std::cerr << "ALSA snd_pcm_readi < 0 = " << frames << std::endl;
					}
					restart = true;
				}
				break;
			}
		}

		if (restart) {
			continue;
		}

		if (cfg->debug() && frames != (snd_pcm_sframes_t)buffer.size()) {
			std::cerr << "ALSA short read, expected " << buffer.size() << " wrote " << frames << std::endl;
		}

		for (int i = 0; i < frames; ++i) {
			bufferf[i] = buffer[i] * 1.0 / 32768.0f;
		}

		get_listener()->input_callback(this, bufferf.data(), frames);
	}
}