Use "= default" to denote default constructor or destructor
[WebKit-https.git] / Source / WebCore / platform / audio / mac / CAAudioStreamDescription.cpp
1 /*
2  * Copyright (C) 2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "CAAudioStreamDescription.h"
28
29 namespace WebCore {
30
31 CAAudioStreamDescription::CAAudioStreamDescription()
32     : m_streamDescription({ })
33 {
34 }
35     
36 CAAudioStreamDescription::~CAAudioStreamDescription() = default;
37
38 CAAudioStreamDescription::CAAudioStreamDescription(const AudioStreamBasicDescription &desc)
39     : m_streamDescription(desc)
40 {
41 }
42
43 CAAudioStreamDescription::CAAudioStreamDescription(double sampleRate, uint32_t numChannels, PCMFormat format, bool isInterleaved)
44 {
45     m_streamDescription.mFormatID = kAudioFormatLinearPCM;
46     m_streamDescription.mSampleRate = sampleRate;
47     m_streamDescription.mFramesPerPacket = 1;
48     m_streamDescription.mChannelsPerFrame = numChannels;
49     m_streamDescription.mBytesPerFrame = 0;
50     m_streamDescription.mBytesPerPacket = 0;
51     m_streamDescription.mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
52     m_streamDescription.mReserved = 0;
53
54     int wordsize;
55     switch (format) {
56     case Int16:
57         wordsize = 2;
58         m_streamDescription.mFormatFlags |= kAudioFormatFlagIsSignedInteger;
59         break;
60     case Int32:
61         wordsize = 4;
62         m_streamDescription.mFormatFlags |= kAudioFormatFlagIsSignedInteger;
63         break;
64     case Float32:
65         wordsize = 4;
66         m_streamDescription.mFormatFlags |= kAudioFormatFlagIsFloat;
67         break;
68     case Float64:
69         wordsize = 8;
70         m_streamDescription.mFormatFlags |= kAudioFormatFlagIsFloat;
71         break;
72     case None:
73         ASSERT_NOT_REACHED();
74         wordsize = 0;
75         break;
76     }
77
78     m_streamDescription.mBitsPerChannel = wordsize * 8;
79     if (isInterleaved)
80         m_streamDescription.mBytesPerFrame = m_streamDescription.mBytesPerPacket = wordsize * numChannels;
81     else {
82         m_streamDescription.mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
83         m_streamDescription.mBytesPerFrame = m_streamDescription.mBytesPerPacket = wordsize;
84     }
85 }
86
87 const PlatformDescription& CAAudioStreamDescription::platformDescription() const
88 {
89     m_platformDescription = { PlatformDescription::CAAudioStreamBasicType, &m_streamDescription };
90     return m_platformDescription;
91 }
92
93 AudioStreamDescription::PCMFormat CAAudioStreamDescription::format() const
94 {
95     if (m_format != None)
96         return m_format;
97
98     if (m_streamDescription.mFormatID != kAudioFormatLinearPCM)
99         return None;
100     if (m_streamDescription.mFramesPerPacket != 1)
101         return None;
102     if (m_streamDescription.mBytesPerFrame != m_streamDescription.mBytesPerPacket)
103         return None;
104     if (m_streamDescription.mBitsPerChannel / sizeof(double) > m_streamDescription.mBytesPerFrame)
105         return None;
106     if (!m_streamDescription.mChannelsPerFrame)
107         return None;
108
109     unsigned wordsize = m_streamDescription.mBytesPerFrame;
110     if (isInterleaved()) {
111         if (wordsize % m_streamDescription.mChannelsPerFrame)
112             return None;
113
114         wordsize /= m_streamDescription.mChannelsPerFrame;
115     }
116
117     if (isNativeEndian() && wordsize * sizeof(double) == m_streamDescription.mBitsPerChannel) {
118         // Packed and native endian, good
119         if (m_streamDescription.mFormatFlags & kLinearPCMFormatFlagIsFloat) {
120             if (m_streamDescription.mFormatFlags & (kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagsSampleFractionMask))
121                 return None;
122
123             if (wordsize == sizeof(float))
124                 return m_format = Float32;
125             if (wordsize == sizeof(double))
126                 return m_format = Float64;
127
128             return None;
129         }
130
131         if (m_streamDescription.mFormatFlags & kLinearPCMFormatFlagIsSignedInteger) {
132             unsigned fractionBits = (m_streamDescription.mFormatFlags & kLinearPCMFormatFlagsSampleFractionMask) >> kLinearPCMFormatFlagsSampleFractionShift;
133             if (!fractionBits) {
134                 if (wordsize == sizeof(int16_t))
135                     return m_format = Int16;
136                 if (wordsize == sizeof(int32_t))
137                     return m_format = Int32;
138             }
139         }
140     }
141
142     return None;
143 }
144
145 bool operator==(const AudioStreamBasicDescription& a, const AudioStreamBasicDescription& b)
146 {
147     return a.mSampleRate == b.mSampleRate
148         && a.mFormatID == b.mFormatID
149         && a.mFormatFlags == b.mFormatFlags
150         && a.mBytesPerPacket == b.mBytesPerPacket
151         && a.mFramesPerPacket == b.mFramesPerPacket
152         && a.mBytesPerFrame == b.mBytesPerFrame
153         && a.mChannelsPerFrame == b.mChannelsPerFrame
154         && a.mBitsPerChannel == b.mBitsPerChannel;
155 }
156
157 }