summaryrefslogtreecommitdiff
path: root/www/chromium-uc/files/sndio_output.cc
diff options
context:
space:
mode:
Diffstat (limited to 'www/chromium-uc/files/sndio_output.cc')
-rw-r--r--www/chromium-uc/files/sndio_output.cc183
1 files changed, 0 insertions, 183 deletions
diff --git a/www/chromium-uc/files/sndio_output.cc b/www/chromium-uc/files/sndio_output.cc
deleted file mode 100644
index bf22ae1..0000000
--- a/www/chromium-uc/files/sndio_output.cc
+++ /dev/null
@@ -1,183 +0,0 @@
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/logging.h"
6#include "base/time/time.h"
7#include "base/time/default_tick_clock.h"
8#include "media/audio/audio_manager_base.h"
9#include "media/base/audio_timestamp_helper.h"
10#include "media/audio/sndio/sndio_output.h"
11
12namespace media {
13
14static const SampleFormat kSampleFormat = kSampleFormatS16;
15
16void SndioAudioOutputStream::OnMoveCallback(void *arg, int delta) {
17 SndioAudioOutputStream* self = static_cast<SndioAudioOutputStream*>(arg);
18
19 self->hw_delay -= delta;
20}
21
22void SndioAudioOutputStream::OnVolCallback(void *arg, unsigned int vol) {
23 SndioAudioOutputStream* self = static_cast<SndioAudioOutputStream*>(arg);
24
25 self->vol = vol;
26}
27
28void *SndioAudioOutputStream::ThreadEntry(void *arg) {
29 SndioAudioOutputStream* self = static_cast<SndioAudioOutputStream*>(arg);
30
31 self->ThreadLoop();
32 return NULL;
33}
34
35SndioAudioOutputStream::SndioAudioOutputStream(const AudioParameters& params,
36 AudioManagerBase* manager)
37 : manager(manager),
38 params(params),
39 audio_bus(AudioBus::Create(params)),
40 state(kClosed),
41 mutex(PTHREAD_MUTEX_INITIALIZER) {
42}
43
44SndioAudioOutputStream::~SndioAudioOutputStream() {
45 if (state != kClosed)
46 Close();
47}
48
49bool SndioAudioOutputStream::Open() {
50 struct sio_par par;
51 int sig;
52
53 if (params.format() != AudioParameters::AUDIO_PCM_LINEAR &&
54 params.format() != AudioParameters::AUDIO_PCM_LOW_LATENCY) {
55 LOG(WARNING) << "Unsupported audio format.";
56 return false;
57 }
58 sio_initpar(&par);
59 par.rate = params.sample_rate();
60 par.pchan = params.channels();
61 par.bits = SampleFormatToBitsPerChannel(kSampleFormat);
62 par.bps = par.bits / 8;
63 par.sig = sig = par.bits != 8 ? 1 : 0;
64 par.le = SIO_LE_NATIVE;
65 par.appbufsz = params.frames_per_buffer();
66
67 hdl = sio_open(SIO_DEVANY, SIO_PLAY, 0);
68 if (hdl == NULL) {
69 LOG(ERROR) << "Couldn't open audio device.";
70 return false;
71 }
72 if (!sio_setpar(hdl, &par) || !sio_getpar(hdl, &par)) {
73 LOG(ERROR) << "Couldn't set audio parameters.";
74 goto bad_close;
75 }
76 if (par.rate != (unsigned int)params.sample_rate() ||
77 par.pchan != (unsigned int)params.channels() ||
78 par.bits != (unsigned int)SampleFormatToBitsPerChannel(kSampleFormat) ||
79 par.sig != (unsigned int)sig ||
80 (par.bps > 1 && par.le != SIO_LE_NATIVE) ||
81 (par.bits != par.bps * 8)) {
82 LOG(ERROR) << "Unsupported audio parameters.";
83 goto bad_close;
84 }
85 state = kStopped;
86 volpending = 0;
87 vol = 0;
88 buffer = new char[audio_bus->frames() * params.GetBytesPerFrame(kSampleFormat)];
89 sio_onmove(hdl, &OnMoveCallback, this);
90 sio_onvol(hdl, &OnVolCallback, this);
91 return true;
92 bad_close:
93 sio_close(hdl);
94 return false;
95}
96
97void SndioAudioOutputStream::Close() {
98 if (state == kClosed)
99 return;
100 if (state == kRunning)
101 Stop();
102 state = kClosed;
103 delete [] buffer;
104 sio_close(hdl);
105 manager->ReleaseOutputStream(this); // Calls the destructor
106}
107
108void SndioAudioOutputStream::Start(AudioSourceCallback* callback) {
109 state = kRunning;
110 hw_delay = 0;
111 source = callback;
112 sio_start(hdl);
113 if (pthread_create(&thread, NULL, &ThreadEntry, this) != 0) {
114 LOG(ERROR) << "Failed to create real-time thread.";
115 sio_stop(hdl);
116 state = kStopped;
117 }
118}
119
120void SndioAudioOutputStream::Stop() {
121 if (state == kStopped)
122 return;
123 state = kStopWait;
124 pthread_join(thread, NULL);
125 sio_stop(hdl);
126 state = kStopped;
127}
128
129void SndioAudioOutputStream::SetVolume(double v) {
130 pthread_mutex_lock(&mutex);
131 vol = v * SIO_MAXVOL;
132 volpending = 1;
133 pthread_mutex_unlock(&mutex);
134}
135
136void SndioAudioOutputStream::GetVolume(double* v) {
137 pthread_mutex_lock(&mutex);
138 *v = vol * (1. / SIO_MAXVOL);
139 pthread_mutex_unlock(&mutex);
140}
141
142// This stream is always used with sub second buffer sizes, where it's
143// sufficient to simply always flush upon Start().
144void SndioAudioOutputStream::Flush() {}
145
146void SndioAudioOutputStream::ThreadLoop(void) {
147 int avail, count, result;
148
149 while (state == kRunning) {
150 // Update volume if needed
151 pthread_mutex_lock(&mutex);
152 if (volpending) {
153 volpending = 0;
154 sio_setvol(hdl, vol);
155 }
156 pthread_mutex_unlock(&mutex);
157
158 // Get data to play
159 const base::TimeDelta delay = AudioTimestampHelper::FramesToTime(hw_delay,
160 params.sample_rate());
161 count = source->OnMoreData(delay, base::TimeTicks::Now(), 0, audio_bus.get());
162 audio_bus->ToInterleaved<SignedInt16SampleTypeTraits>(count, reinterpret_cast<int16_t*>(buffer));
163 if (count == 0) {
164 // We have to submit something to the device
165 count = audio_bus->frames();
166 memset(buffer, 0, count * params.GetBytesPerFrame(kSampleFormat));
167 LOG(WARNING) << "No data to play, running empty cycle.";
168 }
169
170 // Submit data to the device
171 avail = count * params.GetBytesPerFrame(kSampleFormat);
172 result = sio_write(hdl, buffer, avail);
173 if (result == 0) {
174 LOG(WARNING) << "Audio device disconnected.";
175 break;
176 }
177
178 // Update hardware pointer
179 hw_delay += count;
180 }
181}
182
183} // namespace media