![]() |
Mixxx
|
00001 00007 /*************************************************************************** 00008 * * 00009 * This program is free software; you can redistribute it and/or modify * 00010 * it under the terms of the GNU General Public License as published by * 00011 * the Free Software Foundation; either version 2 of the License, or * 00012 * (at your option) any later version. * 00013 * * 00014 ***************************************************************************/ 00015 00016 #include <QtCore> 00017 #include "soundmanagerutil.h" 00018 00024 ChannelGroup::ChannelGroup(unsigned char channelBase, unsigned char channels) 00025 : m_channelBase(channelBase) 00026 , m_channels(channels) { 00027 } 00028 00032 unsigned char ChannelGroup::getChannelBase() const { 00033 return m_channelBase; 00034 } 00035 00039 unsigned char ChannelGroup::getChannelCount() const { 00040 return m_channels; 00041 } 00042 00048 bool ChannelGroup::operator==(const ChannelGroup &other) const { 00049 return m_channelBase == other.m_channelBase 00050 && m_channels == other.m_channels; 00051 } 00052 00059 bool ChannelGroup::clashesWith(const ChannelGroup &other) const { 00060 if (m_channels == 0 || other.m_channels == 0) { 00061 return false; // can't clash if there are no channels in use 00062 } 00063 return (m_channelBase > other.m_channelBase 00064 && m_channelBase < other.m_channelBase + other.m_channels) 00065 || 00066 (other.m_channelBase > m_channelBase 00067 && other.m_channelBase < m_channelBase + m_channels) 00068 || m_channelBase == other.m_channelBase; 00069 } 00070 00075 unsigned int ChannelGroup::getHash() const { 00076 return 0 | (m_channels << 8) | m_channelBase; 00077 } 00078 00085 AudioPath::AudioPath(unsigned char channelBase, unsigned char channels) 00086 : m_channelGroup(channelBase, channels) { 00087 } 00088 00092 AudioPathType AudioPath::getType() const { 00093 return m_type; 00094 } 00095 00099 ChannelGroup AudioPath::getChannelGroup() const { 00100 return m_channelGroup; 00101 } 00102 00106 unsigned char AudioPath::getIndex() const { 00107 return m_index; 00108 } 00109 00114 bool AudioPath::operator==(const AudioPath &other) const { 00115 return m_type == other.m_type 00116 && m_index == other.m_index; 00117 } 00118 00123 unsigned int AudioPath::getHash() const { 00124 return 0 | (m_type << 8) | m_index; 00125 } 00126 00131 bool AudioPath::channelsClash(const AudioPath &other) const { 00132 return m_channelGroup.clashesWith(other.m_channelGroup); 00133 } 00134 00138 QString AudioPath::getString() const { 00139 if (isIndexed(getType())) { 00140 return QString("%1 %2") 00141 .arg(getTrStringFromType(getType())).arg(m_index + 1); 00142 } 00143 return getTrStringFromType(getType()); 00144 } 00145 00151 QString AudioPath::getStringFromType(AudioPathType type) { 00152 switch (type) { 00153 case INVALID: 00154 // this shouldn't happen but g++ complains if I don't 00155 // handle this -- bkgood 00156 return QString::fromAscii("Invalid"); 00157 case MASTER: 00158 return QString::fromAscii("Master"); 00159 case HEADPHONES: 00160 return QString::fromAscii("Headphones"); 00161 case DECK: 00162 return QString::fromAscii("Deck"); 00163 case VINYLCONTROL: 00164 return QString::fromAscii("Vinyl Control"); 00165 case MICROPHONE: 00166 return QString::fromAscii("Microphone"); 00167 case EXTPASSTHROUGH: 00168 return QString::fromAscii("Passthrough"); 00169 } 00170 return QString::fromAscii("Unknown path type %1").arg(type); 00171 } 00172 00177 QString AudioPath::getTrStringFromType(AudioPathType type) { 00178 switch (type) { 00179 case INVALID: 00180 // this shouldn't happen but g++ complains if I don't 00181 // handle this -- bkgood 00182 return QString(QObject::tr("Invalid")); 00183 case MASTER: 00184 return QString(QObject::tr("Master")); 00185 case HEADPHONES: 00186 return QString(QObject::tr("Headphones")); 00187 case DECK: 00188 return QString(QObject::tr("Deck")); 00189 case VINYLCONTROL: 00190 return QString(QObject::tr("Vinyl Control")); 00191 case MICROPHONE: 00192 return QString(QObject::tr("Microphone")); 00193 case EXTPASSTHROUGH: 00194 return QString(QObject::tr("Passthrough")); 00195 } 00196 return QString(QObject::tr("Unknown path type %1")).arg(type); 00197 } 00198 00203 AudioPathType AudioPath::getTypeFromString(QString string) { 00204 string = string.toLower(); 00205 if (string == AudioPath::getStringFromType(AudioPath::MASTER).toLower()) { 00206 return AudioPath::MASTER; 00207 } else if (string == AudioPath::getStringFromType(AudioPath::HEADPHONES).toLower()) { 00208 return AudioPath::HEADPHONES; 00209 } else if (string == AudioPath::getStringFromType(AudioPath::DECK).toLower()) { 00210 return AudioPath::DECK; 00211 } else if (string == AudioPath::getStringFromType(AudioPath::VINYLCONTROL).toLower()) { 00212 return AudioPath::VINYLCONTROL; 00213 } else if (string == AudioPath::getStringFromType(AudioPath::MICROPHONE).toLower()) { 00214 return AudioPath::MICROPHONE; 00215 } else if (string == AudioPath::getStringFromType(AudioPath::EXTPASSTHROUGH).toLower()) { 00216 return AudioPath::EXTPASSTHROUGH; 00217 } else { 00218 return AudioPath::INVALID; 00219 } 00220 } 00221 00226 bool AudioPath::isIndexed(AudioPathType type) { 00227 switch (type) { 00228 case DECK: 00229 case VINYLCONTROL: 00230 case EXTPASSTHROUGH: 00231 return true; 00232 case MICROPHONE: 00233 default: 00234 break; 00235 } 00236 return false; 00237 } 00238 00243 AudioPathType AudioPath::getTypeFromInt(int typeInt) { 00244 if (typeInt < 0 || typeInt >= AudioPath::INVALID) { 00245 return AudioPath::INVALID; 00246 } 00247 return static_cast<AudioPathType>(typeInt); 00248 } 00249 00255 unsigned char AudioPath::channelsNeededForType(AudioPathType type) { 00256 switch (type) { 00257 case AudioPath::MICROPHONE: 00258 return 1; 00259 default: 00260 return 2; 00261 } 00262 } 00263 00267 AudioOutput::AudioOutput(AudioPathType type /* = INVALID */, 00268 unsigned char channelBase /* = 0 */, 00269 unsigned char index /* = 0 */) 00270 : AudioPath(channelBase, AudioPath::channelsNeededForType(type)) { 00271 setType(type); 00272 if (isIndexed(type)) { 00273 m_index = index; 00274 } else { 00275 m_index = 0; 00276 } 00277 } 00278 00283 QDomElement AudioOutput::toXML(QDomElement *element) const { 00284 element->setTagName("output"); 00285 element->setAttribute("type", AudioPath::getStringFromType(m_type)); 00286 element->setAttribute("index", m_index); 00287 element->setAttribute("channel", m_channelGroup.getChannelBase()); 00288 return *element; 00289 } 00290 00295 AudioOutput AudioOutput::fromXML(const QDomElement &xml) { 00296 AudioPathType type(AudioPath::getTypeFromString(xml.attribute("type"))); 00297 unsigned int index(xml.attribute("index", "0").toUInt()); 00298 unsigned int channel(xml.attribute("channel", "0").toUInt()); 00299 return AudioOutput(type, channel, index); 00300 } 00301 00302 //static 00307 QList<AudioPathType> AudioOutput::getSupportedTypes() { 00308 QList<AudioPathType> types; 00309 types.append(MASTER); 00310 types.append(HEADPHONES); 00311 types.append(DECK); 00312 return types; 00313 } 00314 00319 void AudioOutput::setType(AudioPathType type) { 00320 if (AudioOutput::getSupportedTypes().contains(type)) { 00321 m_type = type; 00322 } else { 00323 m_type = AudioPath::INVALID; 00324 } 00325 } 00326 00330 AudioInput::AudioInput(AudioPathType type /* = INVALID */, 00331 unsigned char channelBase /* = 0 */, 00332 unsigned char index /* = 0 */) 00333 : AudioPath(channelBase, AudioPath::channelsNeededForType(type)) { 00334 setType(type); 00335 if (isIndexed(type)) { 00336 m_index = index; 00337 } else { 00338 m_index = 0; 00339 } 00340 } 00341 00346 QDomElement AudioInput::toXML(QDomElement *element) const { 00347 element->setTagName("input"); 00348 element->setAttribute("type", AudioPath::getStringFromType(m_type)); 00349 element->setAttribute("index", m_index); 00350 element->setAttribute("channel", m_channelGroup.getChannelBase()); 00351 return *element; 00352 } 00353 00358 AudioInput AudioInput::fromXML(const QDomElement &xml) { 00359 AudioPathType type(AudioPath::getTypeFromString(xml.attribute("type"))); 00360 unsigned int index(xml.attribute("index", "0").toUInt()); 00361 unsigned int channel(xml.attribute("channel", "0").toUInt()); 00362 return AudioInput(type, channel, index); 00363 } 00364 00369 QList<AudioPathType> AudioInput::getSupportedTypes() { 00370 QList<AudioPathType> types; 00371 #ifdef __VINYLCONTROL__ 00372 // this disables vinyl control for all of the sound devices stuff 00373 // (prefs, etc), minimal ifdefs :) -- bkgood 00374 types.append(VINYLCONTROL); 00375 #endif 00376 types.append(MICROPHONE); 00377 return types; 00378 } 00379 00384 void AudioInput::setType(AudioPathType type) { 00385 if (AudioInput::getSupportedTypes().contains(type)) { 00386 m_type = type; 00387 } else { 00388 m_type = AudioPath::INVALID; 00389 } 00390 } 00391 00395 unsigned int qHash(const ChannelGroup &group) { 00396 return group.getHash(); 00397 } 00398 00402 unsigned int qHash(const AudioOutput &output) { 00403 return output.getHash(); 00404 } 00405 00409 unsigned int qHash(const AudioInput &input) { 00410 return input.getHash(); 00411 }