Bug Summary

File:audio/audio_system.cpp
Location:line 141, column 2
Description:This statement is never executed

Annotated Source Code

1// This file is part of Playslave-C++.
2// Playslave-C++ is licenced under the MIT license: see LICENSE.txt.
3
4/**
5 * @file
6 * Implementation of the AudioSystem class.
7 * @see audio/audio_system.hpp
8 */
9
10#include <algorithm>
11#include <map>
12#include <sstream>
13#include <stdexcept>
14#include <string>
15
16extern "C" {
17#include "libavformat/avformat.h"
18#include "portaudio.h"
19}
20
21#include "portaudiocpp/Device.hxx"
22#include "portaudiocpp/DirectionSpecificStreamParameters.hxx"
23#include "portaudiocpp/InterfaceCallbackStream.hxx"
24#include "portaudiocpp/SampleDataFormat.hxx"
25#include "portaudiocpp/Stream.hxx"
26#include "portaudiocpp/StreamParameters.hxx"
27#include "portaudiocpp/System.hxx"
28#include "portaudiocpp/SystemDeviceIterator.hxx"
29namespace portaudio {
30class CallbackInterface;
31}
32
33#include "../errors.hpp"
34#include "../messages.h"
35#include "../sample_formats.hpp"
36#include "audio.hpp"
37#include "audio_sink.hpp"
38#include "audio_source.hpp"
39#include "audio_system.hpp"
40
41AudioSystem::AudioSystem()
42{
43 portaudio::System::initialize();
44 av_register_all();
45
46 this->device_id = -1;
47}
48
49AudioSystem::~AudioSystem()
50{
51 portaudio::System::terminate();
52}
53
54std::vector<AudioSystem::Device> AudioSystem::GetDevicesInfo()
55{
56 auto &pa = portaudio::System::instance();
57 std::vector<AudioSystem::Device> list;
58
59 for (auto d = pa.devicesBegin(); d != pa.devicesEnd(); ++d) {
60 if (!(*d).isInputOnlyDevice()) {
61 list.push_back(std::make_pair((*d).index(), (*d).name()));
62 }
63 }
64 return list;
65}
66
67bool AudioSystem::IsOutputDevice(int id)
68{
69 auto &pa = portaudio::System::instance();
70 if (id < 0 || id >= pa.deviceCount()) return false;
71
72 portaudio::Device &dev = pa.deviceByIndex(id);
73 return !dev.isInputOnlyDevice();
74}
75
76void AudioSystem::SetDeviceID(int id)
77{
78 this->device_id = std::to_string(id);
79}
80
81Audio *AudioSystem::Load(const std::string &path) const
82{
83 auto source = new AudioSource(path);
84
85 AudioSink::StreamConfigurator config_fn = std::bind(
86 &AudioSystem::Configure, this, source->ChannelCount(),
87 source->OutputSampleFormat(), source->SampleRate(),
88 source->BufferSampleCapacity(), std::placeholders::_1);
89 auto sink = new AudioSink(config_fn, source->BytesPerSample());
90
91 return new Audio(source, sink);
92}
93
94portaudio::Stream *AudioSystem::Configure(
95 std::uint8_t channel_count, SampleFormat sample_format,
96 double sample_rate, size_t buffer_size,
97 portaudio::CallbackInterface &cb) const
98{
99 const portaudio::Device &device = PaDeviceFrom(this->device_id);
100
101 portaudio::DirectionSpecificStreamParameters out_pars(
102 device, channel_count,
103 PaSampleFormatFrom(sample_format), true,
104 device.defaultLowOutputLatency(), nullptr);
105
106 portaudio::StreamParameters pars(
107 portaudio::DirectionSpecificStreamParameters::null(),
108 out_pars, sample_rate, buffer_size, paClipOff((PaStreamFlags) 0x00000001));
109
110 return new portaudio::InterfaceCallbackStream(pars, cb);
111}
112
113const portaudio::Device &AudioSystem::PaDeviceFrom(const std::string &id_string)
114 const
115{
116 auto &pa = portaudio::System::instance();
117
118 PaDeviceIndex id_pa = 0;
119
120 std::istringstream is(id_string);
121 is >> id_pa;
122
123 if (id_pa >= pa.deviceCount()) {
124 throw ConfigError(MSG_DEV_BADID);
125 }
126
127 return pa.deviceByIndex(id_pa);
128}
129
130/// Mappings from SampleFormats to their equivalent PaSampleFormats.
131static const std::map<SampleFormat, portaudio::SampleDataFormat> pa_from_sf = {
132 { SampleFormat::PACKED_UNSIGNED_INT_8, portaudio::UINT8 },
133 { SampleFormat::PACKED_SIGNED_INT_16, portaudio::INT16 },
134 { SampleFormat::PACKED_SIGNED_INT_32, portaudio::INT32 },
135 { SampleFormat::PACKED_FLOAT_32, portaudio::FLOAT32 }
136};
137
138portaudio::SampleDataFormat AudioSystem::PaSampleFormatFrom(SampleFormat fmt)
139 const
140{
141 try
This statement is never executed
142 {
143 return pa_from_sf.at(fmt);
144 }
145 catch (std::out_of_range)
146 {
147 throw FileError(MSG_DECODE_BADRATE);
148 }
149}