Repository: Rapptz/discord.py
File: discord/opus.py (Python)

Code before:
    SAMPLE_SIZE = struct.calcsize('h') * CHANNELS
    SAMPLES_PER_FRAME = int(SAMPLING_RATE / 1000 * FRAME_LENGTH)

    FRAME_SIZE = SAMPLES_PER_FRAME * SAMPLE_SIZE

    @staticmethod
    def get_opus_version() -> str:
        if not is_loaded() and not _load_default():
            raise OpusNotLoaded()

        return _lib.opus_get_version_string().decode('utf-8')


class Encoder(_OpusStruct):
    def __init__(
        self,
        *,
        application: APPLICATION_CTL = 'audio',
        bitrate: int = 128,
        fec: bool = True,
        packet_loss_pct: float = 0.15,
        bandwidth: BAND_CTL = 'full',
        signal_type: SIGNAL_CTL = 'auto',
    ):
        if application not in application_ctl:
            raise KeyError(f'{application} is not a valid application setting. Try one of: {"".join(application_ctl)}')

        if not 16 <= bitrate <= 512:
            raise ValueError(f'bitrate must be between 16 and 512, not {bitrate}')

        if not 0 < packet_loss_pct <= 1.0:
            raise ValueError(f'packet_loss_pct must be a positive number less than or equal to 1, not {packet_loss_pct}')

        _OpusStruct.get_opus_version()  # lazy loads the opus library

        self.application: int = application_ctl[application]
        self._state: EncoderStruct = self._create_state()

        self.set_bitrate(bitrate)
        self.set_fec(fec)
        if fec:
            self.set_expected_packet_loss_percent(packet_loss_pct)
        self.set_bandwidth(bandwidth)
        self.set_signal_type(signal_type)

    def __del__(self) -> None:
        if hasattr(self, '_state'):
            _lib.opus_encoder_destroy(self._state)
            # This is a destructor, so it's okay to assign None
            self._state = None  # type: ignore


Review comment (suggestion):
```suggestion
            raise ValueError(f'{application} is not a valid application setting. Try one of: {"".join(application_ctl)}')
```

Code after:

        return _lib.opus_get_version_string().decode('utf-8')


class Encoder(_OpusStruct):
    def __init__(
        self,
        *,
        application: APPLICATION_CTL = 'audio',
        bitrate: int = 128,
        fec: bool = True,
        expected_packet_loss: float = 0.15,
        bandwidth: BAND_CTL = 'full',
        signal_type: SIGNAL_CTL = 'auto',
    ):
        if application not in application_ctl:
            raise ValueError(f'{application} is not a valid application setting. Try one of: {"".join(application_ctl)}')

        if not 16 <= bitrate <= 512:
            raise ValueError(f'bitrate must be between 16 and 512, not {bitrate}')

        if not 0 < expected_packet_loss <= 1.0:
            raise ValueError(
                f'expected_packet_loss must be a positive number less than or equal to 1, not {expected_packet_loss}'
            )

        _OpusStruct.get_opus_version()  # lazy loads the opus library

        self.application: int = application_ctl[application]
        self._state: EncoderStruct = self._create_state()

        self.set_bitrate(bitrate)
        self.set_fec(fec)
        if fec:
            self.set_expected_packet_loss_percent(expected_packet_loss)
        self.set_bandwidth(bandwidth)
        self.set_signal_type(signal_type)

    def __del__(self) -> None:
        if hasattr(self, '_state'):
            _lib.opus_encoder_destroy(self._state)
            # This is a destructor, so it's okay to assign None
            self._state = None  # type: ignore

    def _create_state(self) -> EncoderStruct:
        ret = ctypes.c_int()
        return _lib.opus_encoder_create(self.SAMPLING_RATE, self.CHANNELS, self.application, ctypes.byref(ret))

    def set_bitrate(self, kbps: int) -> int:
        kbps = min(512, max(16, int(kbps)))