f4bfae6cee75480180cc8aa7a46c202218985e1d
[blender.git] / intern / audaspace / intern / AUD_SequencerHandle.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * Copyright 2009-2011 Jörg Hermann Müller
5  *
6  * This file is part of AudaSpace.
7  *
8  * Audaspace is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * AudaSpace is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with Audaspace; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21  *
22  * ***** END GPL LICENSE BLOCK *****
23  */
24
25 /** \file audaspace/intern/AUD_SequencerHandle.cpp
26  *  \ingroup audaspaceintern
27  */
28
29
30 #include "AUD_SequencerHandle.h"
31 #include "AUD_ReadDevice.h"
32
33 AUD_SequencerHandle::AUD_SequencerHandle(AUD_Reference<AUD_SequencerEntry> entry, AUD_ReadDevice& device) :
34         m_entry(entry),
35         m_status(0),
36         m_pos_status(0),
37         m_sound_status(0),
38         m_device(device)
39 {
40         if(!entry->m_sound.isNull())
41         {
42                 m_handle = device.play(entry->m_sound, true);
43                 m_3dhandle = AUD_Reference<AUD_I3DHandle>(m_handle);
44         }
45 }
46
47 AUD_SequencerHandle::~AUD_SequencerHandle()
48 {
49         stop();
50 }
51
52 int AUD_SequencerHandle::compare(AUD_Reference<AUD_SequencerEntry> entry) const
53 {
54         if(m_entry->getID() < entry->getID())
55                 return -1;
56         else if(m_entry->getID() == entry->getID())
57                 return 0;
58         return 1;
59 }
60
61 void AUD_SequencerHandle::stop()
62 {
63         if(!m_handle.isNull())
64                 m_handle->stop();
65 }
66
67 void AUD_SequencerHandle::update(float position, float frame, float fps)
68 {
69         if(!m_handle.isNull())
70         {
71                 m_entry->lock();
72                 if(position >= m_entry->m_end && m_entry->m_end >= 0)
73                         m_handle->pause();
74                 else if(position >= m_entry->m_begin)
75                         m_handle->resume();
76
77                 if(m_sound_status != m_entry->m_sound_status)
78                 {
79                         if(!m_handle.isNull())
80                                 m_handle->stop();
81
82                         if(!m_entry->m_sound.isNull())
83                         {
84                                 m_handle = m_device.play(m_entry->m_sound, true);
85                                 m_3dhandle = AUD_Reference<AUD_I3DHandle>(m_handle);
86                         }
87
88                         m_sound_status = m_entry->m_sound_status;
89                         m_pos_status--;
90                         m_status--;
91                 }
92
93                 if(m_pos_status != m_entry->m_pos_status)
94                 {
95                         seek(position);
96
97                         m_pos_status = m_entry->m_pos_status;
98                 }
99
100                 if(m_status != m_entry->m_status)
101                 {
102                         m_3dhandle->setRelative(m_entry->m_relative);
103                         m_3dhandle->setVolumeMaximum(m_entry->m_volume_max);
104                         m_3dhandle->setVolumeMinimum(m_entry->m_volume_min);
105                         m_3dhandle->setDistanceMaximum(m_entry->m_distance_max);
106                         m_3dhandle->setDistanceReference(m_entry->m_distance_reference);
107                         m_3dhandle->setAttenuation(m_entry->m_attenuation);
108                         m_3dhandle->setConeAngleOuter(m_entry->m_cone_angle_outer);
109                         m_3dhandle->setConeAngleInner(m_entry->m_cone_angle_inner);
110                         m_3dhandle->setConeVolumeOuter(m_entry->m_cone_volume_outer);
111
112                         m_status = m_entry->m_status;
113                 }
114
115                 float value;
116
117                 m_entry->m_volume.read(frame, &value);
118                 m_handle->setVolume(value);
119                 m_entry->m_pitch.read(frame, &value);
120                 m_handle->setPitch(value);
121                 m_entry->m_panning.read(frame, &value);
122                 AUD_SoftwareDevice::setPanning(m_handle.get(), value);
123
124                 AUD_Vector3 v, v2;
125                 AUD_Quaternion q;
126
127                 m_entry->m_orientation.read(frame, q.get());
128                 m_3dhandle->setSourceOrientation(q);
129                 m_entry->m_location.read(frame, v.get());
130                 m_3dhandle->setSourceLocation(v);
131                 m_entry->m_location.read(frame + 1, v2.get());
132                 v2 -= v;
133                 m_3dhandle->setSourceVelocity(v2 * fps);
134
135                 if(m_entry->m_muted)
136                         m_handle->setVolume(0);
137                 m_entry->unlock();
138         }
139 }
140
141 void AUD_SequencerHandle::seek(float position)
142 {
143         if(!m_handle.isNull())
144         {
145                 m_entry->lock();
146                 if(position >= m_entry->m_end && m_entry->m_end >= 0)
147                 {
148                         m_handle->pause();
149                         m_entry->unlock();
150                         return;
151                 }
152
153                 float seekpos = position - m_entry->m_begin;
154                 if(seekpos < 0)
155                         seekpos = 0;
156                 seekpos += m_entry->m_skip;
157                 m_handle->setPitch(1.0f);
158                 m_handle->seek(seekpos);
159                 if(position < m_entry->m_begin)
160                         m_handle->pause();
161                 else
162                         m_handle->resume();
163                 m_entry->unlock();
164         }
165 }