FreeBSD Bugzilla – Attachment 205403 Details for
Bug 238869
www/chromium: sndio input implementation
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
sndio_input.cc sndio_input.h
patch_sndio_input.diff (text/plain), 8.72 KB, created by
zielonka michal
on 2019-06-28 19:39:54 UTC
(
hide
)
Description:
sndio_input.cc sndio_input.h
Filename:
MIME Type:
Creator:
zielonka michal
Created:
2019-06-28 19:39:54 UTC
Size:
8.72 KB
patch
obsolete
>diff --git a/www/chromium/files/sndio_input.cc b/www/chromium/files/sndio_input.cc >index 4a00d8ac1083..e4f6e6204f2b 100644 >--- a/www/chromium/files/sndio_input.cc >+++ b/www/chromium/files/sndio_input.cc >@@ -12,20 +12,29 @@ > #include "base/message_loop/message_loop.h" > #include "media/audio/openbsd/audio_manager_openbsd.h" > #include "media/audio/audio_manager.h" >+#include "media/base/audio_timestamp_helper.h" > > namespace media { > > static const SampleFormat kSampleFormat = kSampleFormatS16; > >+// Number of blocks of buffers used in the |fifo_|. >+const int kNumberOfBlocksBufferInFifo = 2; >+ > void sndio_in_onmove(void *arg, int delta) { >- NOTIMPLEMENTED(); > SndioAudioInputStream* self = static_cast<SndioAudioInputStream*>(arg); > >- self->hw_delay_ = delta - self->params_.GetBytesPerFrame(kSampleFormat); >+ self->hw_delay_ = delta; >+} >+ >+void sndio_in_onvol(void *arg, unsigned int volume) { >+ SndioAudioInputStream* self = static_cast<SndioAudioInputStream*>(arg); >+ pthread_mutex_lock(&(self->mutex)); >+ self->vol = volume; >+ pthread_mutex_unlock(&(self->mutex)); > } > > void *sndio_in_threadstart(void *arg) { >- NOTIMPLEMENTED(); > SndioAudioInputStream* self = static_cast<SndioAudioInputStream*>(arg); > > self->ReadAudio(); >@@ -45,10 +54,17 @@ SndioAudioInputStream::SndioAudioInputStream(AudioManagerBase* audio_manager, > callback_(NULL), > device_handle_(NULL), > read_callback_behind_schedule_(false), >- audio_bus_(AudioBus::Create(params)) { >+ state(kClosed), >+ mutex(PTHREAD_MUTEX_INITIALIZER), >+ fifo_(params.channels(), >+ params.frames_per_buffer(), >+ kNumberOfBlocksBufferInFifo) { > } > >-SndioAudioInputStream::~SndioAudioInputStream() {} >+SndioAudioInputStream::~SndioAudioInputStream() { >+ if (state != kClosed) >+ Close(); >+} > > bool SndioAudioInputStream::Open() { > struct sio_par par; >@@ -59,21 +75,10 @@ bool SndioAudioInputStream::Open() { > > if (params_.format() != AudioParameters::AUDIO_PCM_LINEAR && > params_.format() != AudioParameters::AUDIO_PCM_LOW_LATENCY) { >- LOG(WARNING) << "Unsupported audio format."; >+ LOG(ERROR) << "Unsupported audio format."; > return false; > } > >- sio_initpar(&par); >- par.rate = params_.sample_rate(); >- par.pchan = params_.channels(); >- par.bits = SampleFormatToBytesPerChannel(kSampleFormat); >- par.bps = par.bits / 8; >- par.sig = sig = par.bits != 8 ? 1 : 0; >- par.le = SIO_LE_NATIVE; >- par.appbufsz = params_.frames_per_buffer(); >- sndio_rec_bufsz_ = par.bufsz; >- sndio_rec_bufsize_ = par.round * par.bps * par.rchan; >- > device_handle_ = sio_open(SIO_DEVANY, SIO_REC, 0); > > if (device_handle_ == NULL) { >@@ -81,14 +86,24 @@ bool SndioAudioInputStream::Open() { > return false; > } > >+ sio_initpar(&par); >+ >+ par.rate = params_.sample_rate(); >+ par.rchan = params_.channels(); >+ par.bps = SampleFormatToBytesPerChannel(kSampleFormat); >+ par.bits = par.bps * 8; >+ par.sig = sig = par.bits != 8 ? 1 : 0; >+ par.le = SIO_LE_NATIVE; >+ par.appbufsz = 10 * params_.channels() * par.bps * params_.frames_per_buffer(); >+ > if (!sio_setpar(device_handle_, &par) || !sio_getpar(device_handle_, &par)) { > LOG(ERROR) << "Couldn't set audio parameters."; > goto bad_close; > } > > if (par.rate != (unsigned int)params_.sample_rate() || >- par.pchan != (unsigned int)params_.channels() || >- par.bits != (unsigned int)SampleFormatToBytesPerChannel(kSampleFormat) || >+ par.rchan != (unsigned int)params_.channels() || >+ par.bps != (unsigned int)SampleFormatToBytesPerChannel(kSampleFormat) || > par.sig != (unsigned int)sig || > (par.bps > 1 && par.le != SIO_LE_NATIVE) || > (par.bits != par.bps * 8)) { >@@ -96,7 +111,16 @@ bool SndioAudioInputStream::Open() { > goto bad_close; > } > sio_onmove(device_handle_, sndio_in_onmove, this); >+ sio_onvol(device_handle_, sndio_in_onvol, this); >+ >+ vol = SIO_MAXVOL; >+ >+ if (!sio_start(device_handle_)) { >+ LOG(ERROR) << "Couldn't start device."; >+ goto bad_close; >+ } > >+ state = kStopped; > audio_buffer_.reset(new uint8_t[bytes_per_buffer_]); > > return true; >@@ -110,32 +134,80 @@ void SndioAudioInputStream::Start(AudioInputCallback* callback) { > callback_ = callback; > StartAgc(); > >+ state = kRunning; > // We start reading data half |buffer_duration_| later than when the > // buffer might have got filled, to accommodate some delays in the audio > // driver. This could also give us a smooth read sequence going forward. > base::TimeDelta delay = buffer_duration_ + buffer_duration_ / 2; > next_read_time_ = base::TimeTicks::Now() + delay; >- if (pthread_create(&thread_, NULL, sndio_in_threadstart, this) != 0) >+ >+ if (pthread_create(&thread_, NULL, sndio_in_threadstart, this) != 0) { > LOG(ERROR) << "Failed to create real-time thread."; >+ sio_stop(device_handle_); >+ state = kStopped; >+ } > } > > void SndioAudioInputStream::ReadAudio() { >- NOTIMPLEMENTED(); >+ DCHECK(callback_); >+ >+ double normalized_volume = 1.0; >+ void* data = audio_buffer_.get(); >+ int number_of_bytes = 0; >+ int number_of_frames = 0; >+ int bpc = SampleFormatToBytesPerChannel(kSampleFormat); >+ const AudioBus* audio_bus; >+ base::TimeTicks capture_time = base::TimeTicks::Now(); >+ >+ while (state == kRunning) { >+ normalized_volume = GetVolume()/SIO_MAXVOL; >+ >+ capture_time = base::TimeTicks::Now() - base::TimeDelta::FromMicroseconds(hw_delay_ * base::Time::kMicrosecondsPerSecond / static_cast<float>(params_.sample_rate())); >+ >+ number_of_bytes = sio_read(device_handle_, data, bytes_per_buffer_); >+ number_of_frames = number_of_bytes/(bpc * params_.channels()); >+ >+ fifo_.Push(data, number_of_frames, bpc); >+ >+ while (fifo_.available_blocks()) { >+ audio_bus = fifo_.Consume(); >+ >+ callback_->OnData(audio_bus, capture_time, normalized_volume); >+ >+ // Move the capture time forward for each vended block. >+ capture_time += AudioTimestampHelper::FramesToTime(audio_bus->frames(), >+ params_.sample_rate()); >+ } >+ } > } > > void SndioAudioInputStream::Stop() { >+ >+ if (state == kStopped) >+ return; >+ > if (!device_handle_ || !callback_) > return; > > StopAgc(); > >+ state = kStopWait; > pthread_join(thread_, NULL); > sio_stop(device_handle_); >- >+ state = kStopped; >+ fifo_.Clear(); > callback_ = NULL; > } > > void SndioAudioInputStream::Close() { >+ if (state == kClosed) >+ return; >+ >+ if (state == kRunning) >+ Stop(); >+ >+ state = kClosed; >+ > if (device_handle_) { > sio_close(device_handle_); > audio_buffer_.reset(); >@@ -149,13 +221,15 @@ double SndioAudioInputStream::GetMaxVolume() { > return static_cast<double>(SIO_MAXVOL); > } > >-void SndioAudioInputStream::SetVolume(double volume) { >- NOTIMPLEMENTED(); >+void SndioAudioInputStream::SetVolume(double v) { >+ pthread_mutex_lock(&mutex); >+ int res = sio_setvol(device_handle_, v); >+ vol = v; >+ pthread_mutex_unlock(&mutex); > } > > double SndioAudioInputStream::GetVolume() { >- long current_volume = 0; >- return static_cast<double>(current_volume); >+ return vol; > } > > bool SndioAudioInputStream::IsMuted() { >diff --git a/www/chromium/files/sndio_input.h b/www/chromium/files/sndio_input.h >index 2f3fca97a3a3..eb5906998e8d 100644 >--- a/www/chromium/files/sndio_input.h >+++ b/www/chromium/files/sndio_input.h >@@ -17,6 +17,7 @@ > #include "media/audio/audio_io.h" > #include "media/audio/audio_device_description.h" > #include "media/base/audio_parameters.h" >+#include "media/base/audio_block_fifo.h" > > namespace media { > >@@ -67,6 +68,13 @@ class SndioAudioInputStream : public AgcAudioStream<AudioInputStream> { > friend void *sndio_in_threadstart(void *arg); > > private: >+ enum StreamState { >+ kClosed, // Not opened yet >+ kStopped, // Device opened, but not started yet >+ kRunning, // Started, device playing >+ kStopWait // Stopping, waiting for the real-time thread to exit >+ }; >+ > // Logs the error and invokes any registered callbacks. > void HandleError(const char* method, int error); > >@@ -92,14 +100,22 @@ class SndioAudioInputStream : public AgcAudioStream<AudioInputStream> { > struct sio_hdl* device_handle_; // Handle to the SNDIO PCM recording device. > std::unique_ptr<uint8_t[]> audio_buffer_; // Buffer used for reading audio data. > bool read_callback_behind_schedule_; >- std::unique_ptr<AudioBus> audio_bus_; >+ // Current state of the stream >+ enum StreamState state; > > int hw_delay_; > int sndio_rec_bufsize_; > int sndio_rec_bufsz_; >+ // Current volume in the 0..SIO_MAXVOL range >+ int vol; > > // High priority thread running RealTimeThread() > pthread_t thread_; >+ // Protects vol, volpending and hw_delay >+ pthread_mutex_t mutex; >+ >+ // Holds the data from the OS. >+ AudioBlockFifo fifo_; > > DISALLOW_COPY_AND_ASSIGN(SndioAudioInputStream); > };
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 238869
:
205403
|
206112