Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(563)

Side by Side Diff: experimental/conways_life/audio/web_wav_sound_resource.cc

Issue 10928195: First round of dead file removal (Closed) Base URL: https://github.com/samclegg/nativeclient-sdk.git@master
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Native Client 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 "experimental/conways_life/audio/web_wav_sound_resource.h"
6
7 #include <string.h>
8 #include <algorithm>
9
10 #include "experimental/conways_life/web_resource_loader_inl.h"
11 #include "ppapi/cpp/instance.h"
12 #include "ppapi/cpp/url_response_info.h"
13 #include "ppapi/cpp/var.h"
14
15 namespace {
16 // Wav record descriptor per
17 // https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
18 #pragma pack(push, 1)
19 struct WavRecord {
20 // Header.
21 char header_id[4]; // Should be "RIFF"
22 int32_t record_size; // Should be size of data minus 8
23 char format[4]; // Should be "WAVE"
24 // Subchunk 1, i.e. format descriptor.
25 char format_chunk_id[4]; // Should be "fmt ".
26 int32_t format_chunk_size; // Should be 16.
27 int16_t audio_format; // Should be 1 for uncompressed audio.
28 int16_t num_channels; // 1 for mono, 2 for stereo.
29 int32_t sample_rate;
30 int32_t byte_rate;
31 int16_t block_align;
32 int16_t bits_per_sample;
33 // Data chunk.
34 char data_id[4]; // Should be "data"
35 int32_t audio_chunk_size; // Size of sample data that follows.
36 char audio_data; // The first byte of actual sound data;
37 };
38 #pragma pack(pop)
39
40 // Parse the headers in the url response and return the length of the
41 // resource content ion bytes. Returns 0 in case of error.
42 int GetContentLength(const pp::URLResponseInfo response) {
43 pp::Var header_var = response.GetHeaders();
44 if (!header_var.is_string()) {
45 return 0;
46 }
47
48 static const std::string kContentLengthKey("Content-Length: ");
49 std::string headers = header_var.AsString();
50 size_t i = headers.find(kContentLengthKey);
51 if (i == headers.npos) {
52 return 0;
53 }
54
55 return atoi(headers.substr(i + kContentLengthKey.length()).c_str());
56 }
57
58 // Verify that the wav data in the buffer is valid and playable with
59 // the pepper audio interface.
60 bool VerifyWavData(const char* data, size_t data_size) {
61 // Do we have enough data.
62 if (data_size < sizeof(WavRecord)) {
63 printf("Wav data size = %u is too short.\n",
64 static_cast<uint32_t>(data_size));
65 return false;
66 }
67
68 const WavRecord* wav = reinterpret_cast<const WavRecord*>(data);
69 // Check various chunk formats.
70 if (::strncmp(wav->header_id, "RIFF", 4) != 0 ||
71 ::strncmp(wav->format, "WAVE", 4) != 0 ||
72 ::strncmp(wav->format_chunk_id, "fmt ", 4) != 0 ||
73 ::strncmp(wav->data_id, "data", 4) != 0) {
74 printf("Did not find 'RIFF', 'WAVE' and 'fmt ' headers in wav data.\n");
75 return false;
76 }
77 // Check that we support the audio format.
78 if (wav->sample_rate != 44100 && wav->sample_rate != 48000) {
79 printf("Wav sample rate = %i. MNacl only supports 44100 or 48000.\n",
80 wav->sample_rate);
81 return false;
82 }
83 if (wav->num_channels != 2 || wav->bits_per_sample != 16) {
84 printf("NaCl supports stereo audio and 16-bit per sample at this time.\n");
85 return false;
86 }
87 // Finally, check that the actual data size and wav sample data size match.
88 bool check_audio_size = (wav->audio_chunk_size ==
89 static_cast<int32_t>(data_size - sizeof(WavRecord) + 1));
90 if (!check_audio_size) {
91 printf("Wav audio size: actual = %i, expected = %i\n",
92 wav->audio_chunk_size,
93 static_cast<int>(data_size - sizeof(WavRecord) + 1));
94 }
95 return check_audio_size;
96 }
97
98 } // anonymous namespace
99
100
101 namespace audio {
102
103 WebWavSoundResource::WebWavSoundResource()
104 : is_ready_(false),
105 wav_data_size_(0),
106 received_data_size_(0),
107 loader_(NULL) {
108 }
109
110 WebWavSoundResource::~WebWavSoundResource() {
111 Clear();
112 }
113
114 void WebWavSoundResource::Init(const std::string& url, pp::Instance* instance) {
115 assert(wav_data_.empty()); // Can only init once.
116 if (wav_data_.empty()) {
117 loader_ = new Loader(instance, this);
118 loader_->LoadURL(url);
119 }
120 }
121
122 int32_t WebWavSoundResource::GetSampleRate() const {
123 assert(IsReady());
124 const WavRecord* wav = reinterpret_cast<const WavRecord*>(&wav_data_[0]);
125 return wav->sample_rate;
126 }
127
128 const char* WebWavSoundResource::GetAudioData() const {
129 assert(IsReady());
130 const WavRecord* wav = reinterpret_cast<const WavRecord*>(&wav_data_[0]);
131 return &(wav->audio_data);
132 }
133
134 size_t WebWavSoundResource::GetAudioDataSize() const {
135 assert(IsReady());
136 const WavRecord* wav = reinterpret_cast<const WavRecord*>(&wav_data_[0]);
137 return wav->audio_chunk_size;
138 }
139
140 bool WebWavSoundResource::OnWebResourceLoaderCallback(
141 Loader::DispatchOpCode op_code, Loader* loader) {
142 switch (op_code) {
143 case Loader::kUrlResponseInfoReady: {
144 int content_length = GetContentLength(loader->GetResponseInfo());
145 if (content_length <= 0) {
146 // Either the download failed, or the sound data is bad. Abort.
147 Clear();
148 return false;
149 } else {
150 // Create a local buffer big enough to receive the sound data.
151 wav_data_.reserve(content_length);
152 wav_data_size_ = content_length;
153 received_data_size_ = 0;
154 return true;
155 }
156 break;
157 }
158 case Loader::kDataReceived: {
159 if (received_data_size_ + loader->data_size() > wav_data_size_) {
160 // Size of sound data exceeds expected size. Abort.
161 return false;
162 } else {
163 // Append chunk of data to local sound buffer.
164 ::memcpy(&wav_data_[0] + received_data_size_,
165 loader->buffer(), loader->data_size());
166 received_data_size_ += loader->data_size();
167 return true;
168 }
169 break;
170 }
171 case Loader::kDownloadComplete: {
172 is_ready_ = VerifyWavData(&wav_data_[0], wav_data_size_);
173 if (!is_ready_) {
174 Clear();
175 }
176 return true;
177 break;
178 }
179 }
180 return false;
181 }
182
183 void WebWavSoundResource::OnWebResourceLoaderError(int32_t error,
184 Loader* loader) {
185 }
186
187 void WebWavSoundResource::OnWebResourceLoaderDone(Loader* loader) {
188 loader_->CloseAndDeleteSelf();
189 loader_ = NULL;
190 }
191
192 void WebWavSoundResource::Clear() {
193 is_ready_ = false;
194 wav_data_.clear();
195 wav_data_size_ = 0;
196 received_data_size_ = 0;
197 if (loader_) {
198 loader_->CloseAndDeleteSelf();
199 loader_ = NULL;
200 }
201 }
202
203 } // namespace audio
OLDNEW
« no previous file with comments | « experimental/conways_life/audio/web_wav_sound_resource.h ('k') | experimental/conways_life/build.scons » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698