| // Copyright 2017 Google Inc. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include "starboard/shared/starboard/player/decoded_audio_internal.h" |
| |
| #include <algorithm> |
| |
| #include "starboard/log.h" |
| |
| namespace starboard { |
| namespace shared { |
| namespace starboard { |
| namespace player { |
| |
| DecodedAudio::DecodedAudio() |
| : channels_(0), |
| sample_type_(kSbMediaAudioSampleTypeInt16), |
| storage_type_(kSbMediaAudioFrameStorageTypeInterleaved), |
| pts_(0), |
| size_(0) {} |
| |
| DecodedAudio::DecodedAudio(int channels, |
| SbMediaAudioSampleType sample_type, |
| SbMediaAudioFrameStorageType storage_type, |
| SbMediaTime pts, |
| size_t size) |
| : channels_(channels), |
| sample_type_(sample_type), |
| storage_type_(storage_type), |
| pts_(pts), |
| buffer_(new uint8_t[size]), |
| size_(size) {} |
| |
| int DecodedAudio::frames() const { |
| int bytes_per_sample; |
| if (sample_type_ == kSbMediaAudioSampleTypeInt16) { |
| bytes_per_sample = 2; |
| } else { |
| SB_DCHECK(sample_type_ == kSbMediaAudioSampleTypeFloat32); |
| bytes_per_sample = 4; |
| } |
| SB_DCHECK(size_ % (bytes_per_sample * channels_) == 0); |
| return static_cast<int>(size_ / bytes_per_sample / channels_); |
| } |
| |
| void DecodedAudio::ShrinkTo(size_t new_size) { |
| SB_DCHECK(new_size <= size_); |
| size_ = new_size; |
| } |
| |
| void DecodedAudio::SwitchFormatTo( |
| SbMediaAudioSampleType new_sample_type, |
| SbMediaAudioFrameStorageType new_storage_type) { |
| if (new_sample_type == sample_type_ && new_storage_type == storage_type_) { |
| return; |
| } |
| |
| if (storage_type_ != kSbMediaAudioFrameStorageTypeInterleaved || |
| new_storage_type != kSbMediaAudioFrameStorageTypeInterleaved) { |
| SB_NOTREACHED(); |
| // TODO: Implement switching between other storage type pairs. |
| return; |
| } |
| |
| if (sample_type_ == kSbMediaAudioSampleTypeInt16 && |
| new_sample_type == kSbMediaAudioSampleTypeFloat32 && |
| storage_type_ == kSbMediaAudioFrameStorageTypeInterleaved && |
| new_storage_type == kSbMediaAudioFrameStorageTypeInterleaved) { |
| size_t new_size = sizeof(float) * frames() * channels(); |
| scoped_array<uint8_t> new_buffer(new uint8_t[new_size]); |
| float* new_samples = reinterpret_cast<float*>(new_buffer.get()); |
| int16_t* old_samples = reinterpret_cast<int16_t*>(buffer_.get()); |
| |
| for (int i = 0; i < frames() * channels(); ++i) { |
| new_samples[i] = static_cast<float>(old_samples[i]) / 32768.f; |
| } |
| |
| buffer_.swap(new_buffer); |
| sample_type_ = new_sample_type; |
| size_ = new_size; |
| |
| return; |
| } |
| |
| if (sample_type_ == kSbMediaAudioSampleTypeFloat32 && |
| new_sample_type == kSbMediaAudioSampleTypeInt16 && |
| storage_type_ == kSbMediaAudioFrameStorageTypeInterleaved && |
| new_storage_type == kSbMediaAudioFrameStorageTypeInterleaved) { |
| size_t new_size = sizeof(int16_t) * frames() * channels(); |
| scoped_array<uint8_t> new_buffer(new uint8_t[new_size]); |
| int16_t* new_samples = reinterpret_cast<int16_t*>(new_buffer.get()); |
| float* old_samples = reinterpret_cast<float*>(buffer_.get()); |
| |
| for (int i = 0; i < frames() * channels(); ++i) { |
| float sample = std::max(old_samples[i], -1.f); |
| sample = std::min(sample, 1.f); |
| new_samples[i] = static_cast<int16_t>(sample * 32767.f); |
| } |
| |
| buffer_.swap(new_buffer); |
| sample_type_ = new_sample_type; |
| size_ = new_size; |
| |
| return; |
| } |
| |
| // TODO: Implement switching between other sample and storage types. |
| SB_NOTREACHED(); |
| } |
| |
| } // namespace player |
| } // namespace starboard |
| } // namespace shared |
| } // namespace starboard |