1# This Source Code Form is subject to the terms of the Mozilla Public
2# License, v. 2.0. If a copy of the MPL was not distributed with this
3# file, You can obtain one at https://mozilla.org/MPL/2.0/.
4#
5# This file incorporates work covered by the following copyright and
6# permission notice:
7#
8# Copyright (c) Jeremy Lainé.
9# All rights reserved.
10#
11# Redistribution and use in source and binary forms, with or without
12# modification, are permitted provided that the following conditions are met:
13#
14# * Redistributions of source code must retain the above copyright notice,
15# this list of conditions and the following disclaimer.
16# * Redistributions in binary form must reproduce the above copyright notice,
17# this list of conditions and the following disclaimer in the documentation
18# and/or other materials provided with the distribution.
19# * Neither the name of aiortc nor the names of its contributors may
20# be used to endorse or promote products derived from this software without
21# specific prior written permission.
22#
23# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
27# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
34import fractions
35from typing import Literal
36
37from ..mediastreams import convert_timebase
38from .base import Decoder, Encoder, EncodedPacket
39
40SAMPLE_RATE = 8000
41SAMPLE_WIDTH = 2
42SAMPLES_PER_FRAME = 160
43TIME_BASE = fractions.Fraction(1, 8000)
44
45
46class PcmDecoder(Decoder):
47 def __init__(self, codec_name: Literal["pcm_alaw", "pcm_mulaw"]) -> None:
48 self.codec_name = codec_name
49
50
51class PcmEncoder(Encoder):
52 def __init__(self, codec_name: Literal["pcm_alaw", "pcm_mulaw"]) -> None:
53 self.codec_name = codec_name
54
55 def pack(self, packet: EncodedPacket) -> tuple[list[bytes], int, bool]:
56 timestamp = convert_timebase(packet.pts, packet.time_base, TIME_BASE)
57 return [bytes(packet.data)], timestamp, False
58
59
60class PcmaDecoder(PcmDecoder):
61 def __init__(self) -> None:
62 super().__init__("pcm_alaw")
63
64
65class PcmaEncoder(PcmEncoder):
66 def __init__(self) -> None:
67 super().__init__("pcm_alaw")
68
69
70class PcmuDecoder(PcmDecoder):
71 def __init__(self) -> None:
72 super().__init__("pcm_mulaw")
73
74
75class PcmuEncoder(PcmEncoder):
76 def __init__(self) -> None:
77 super().__init__("pcm_mulaw")