1 /******************************************************************************* 2 * Copyright 2015-2016 Juan Francisco Crespo Galán 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 ******************************************************************************/ 16 17 #include "fx/PlaybackCategory.h" 18 #include "fx/VolumeSound.h" 19 20 AUD_NAMESPACE_BEGIN 21 22 struct HandleData { 23 unsigned int id; 24 PlaybackCategory* category; 25 }; 26 PlaybackCategory(std::shared_ptr<IDevice> device)27PlaybackCategory::PlaybackCategory(std::shared_ptr<IDevice> device) : 28 m_currentID(0), m_device(device), m_status(STATUS_PLAYING), m_volumeStorage(std::make_shared<VolumeStorage>(1.0f)) 29 { 30 } 31 ~PlaybackCategory()32PlaybackCategory::~PlaybackCategory() 33 { 34 stop(); 35 } 36 play(std::shared_ptr<ISound> sound)37std::shared_ptr<IHandle> PlaybackCategory::play(std::shared_ptr<ISound> sound) 38 { 39 std::shared_ptr<ISound> vs(std::make_shared<VolumeSound>(sound, m_volumeStorage)); 40 m_device->lock(); 41 auto handle = m_device->play(vs); 42 if(handle == nullptr) 43 return nullptr; 44 switch (m_status) 45 { 46 case STATUS_PAUSED: 47 handle->pause(); 48 break; 49 default: 50 m_status = STATUS_PLAYING; 51 }; 52 m_handles[m_currentID] = handle; 53 HandleData* data = new HandleData; 54 data->category = this; 55 data->id = m_currentID; 56 handle->setStopCallback(cleanHandleCallback, data); 57 m_device->unlock(); 58 59 m_currentID++; 60 return handle; 61 } 62 resume()63void PlaybackCategory::resume() 64 { 65 m_device->lock(); 66 for(auto i = m_handles.begin(); i != m_handles.end();) 67 { 68 if(i->second->getStatus() == STATUS_INVALID) 69 i = m_handles.erase(i); 70 else 71 { 72 i->second->resume(); 73 i++; 74 } 75 } 76 m_device->unlock(); 77 m_status = STATUS_PLAYING; 78 } 79 pause()80void PlaybackCategory::pause() 81 { 82 m_device->lock(); 83 for(auto i = m_handles.begin(); i != m_handles.end();) 84 { 85 if(i->second->getStatus() == STATUS_INVALID) 86 i = m_handles.erase(i); 87 else 88 { 89 i->second->pause(); 90 i++; 91 } 92 } 93 m_device->unlock(); 94 m_status = STATUS_PAUSED; 95 } 96 getVolume()97float PlaybackCategory::getVolume() 98 { 99 return m_volumeStorage->getVolume(); 100 } 101 setVolume(float volume)102void PlaybackCategory::setVolume(float volume) 103 { 104 m_volumeStorage->setVolume(volume); 105 } 106 stop()107void PlaybackCategory::stop() 108 { 109 m_device->lock(); 110 for(auto i = m_handles.begin(); i != m_handles.end();) 111 { 112 i->second->stop(); 113 if(i->second->getStatus() == STATUS_INVALID) 114 i = m_handles.erase(i); 115 else 116 i++; 117 } 118 m_device->unlock(); 119 m_status = STATUS_STOPPED; 120 } 121 getSharedVolume()122std::shared_ptr<VolumeStorage> PlaybackCategory::getSharedVolume() 123 { 124 return m_volumeStorage; 125 } 126 cleanHandles()127void PlaybackCategory::cleanHandles() 128 { 129 for(auto i = m_handles.begin(); i != m_handles.end();) 130 { 131 if(i->second->getStatus() == STATUS_INVALID) 132 i = m_handles.erase(i); 133 else 134 i++; 135 } 136 } 137 cleanHandleCallback(void * data)138void PlaybackCategory::cleanHandleCallback(void* data) 139 { 140 auto dat = reinterpret_cast<HandleData*>(data); 141 dat->category->m_handles.erase(dat->id); 142 delete dat; 143 } 144 AUD_NAMESPACE_END 145