Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
5cda687
Set Visual Studio flags in CMake
andy-sandbox May 20, 2019
88aa731
Modify __null_backend to compile on Windows
andy-sandbox May 20, 2019
4b86b3e
Modify __audio_buffer to compile on Windows
andy-sandbox May 20, 2019
add97fd
Specify _USE_MATH_DEFINES on Windows
andy-sandbox May 20, 2019
dc8dfbd
Add <atomic> header that was previously only included transitively
andy-sandbox May 20, 2019
7f47153
Cast M_PI to float to avoid narrowing conversion warning
andy-sandbox May 20, 2019
ad43986
Removed unused parameter
andy-sandbox May 20, 2019
be138d2
Use const where possible
andy-sandbox May 20, 2019
7202ebb
Add __windows_backend.h
andy-sandbox May 20, 2019
e7ab4c2
Use forward_list for Windows audio_driver_list
andy-sandbox May 20, 2019
7347d35
Move ASIO audio_device class into its own file
andy-sandbox May 20, 2019
2a860b7
Delegate device selection API calls to __asio_devices
andy-sandbox May 20, 2019
bfd8ff6
Read ASIO driver info from registry
andy-sandbox May 20, 2019
0ef1a24
Ignore win_build directory
andy-sandbox May 20, 2019
7f72d5a
Enumerate ASIO devices
andy-sandbox May 20, 2019
3c1602d
Implement sample rate accessors
andy-sandbox May 20, 2019
8962a9c
Implement buffer size accessors
andy-sandbox May 20, 2019
7f78517
Add audio_device_exception & _running member
andy-sandbox May 20, 2019
9b4adbb
Retrieve the ASIO driver's sample type
andy-sandbox May 20, 2019
966905a
Set the callback for the default (float) sample type
andy-sandbox May 20, 2019
5e19c0e
Implement the ASIO callbacks
andy-sandbox May 20, 2019
8d71eb6
Respond to ASIO buffer_switch message with updated timestamp & position
andy-sandbox May 20, 2019
daca8c3
Fill output buffers
andy-sandbox May 20, 2019
618c651
Fill input buffers
andy-sandbox May 20, 2019
f254785
Make audio devices half-duplex
andy-sandbox May 22, 2019
66dffed
Loop through samples in channel order first when converting
andy-sandbox May 27, 2019
89246a5
Use C++ casts instead of function-style casts
andy-sandbox Jun 2, 2019
38e5b67
Use const methods
andy-sandbox Jun 2, 2019
4a1b58f
Add comment explaining why Realtek ASIO drivers are excluded
andy-sandbox Jun 2, 2019
415b665
Remove C-style comments from header
andy-sandbox Jun 2, 2019
95710ae
Remove using namespace statement from <audio> header
andy-sandbox Jun 2, 2019
9cd0bb3
Change buffers to work with changes in 92ca1045
andy-sandbox Jun 2, 2019
9aa0f29
Add audio_device::start with stop/start callback overloads
andy-sandbox Jun 2, 2019
d50239b
Add stub implementation of set_audio_device_list_callback
andy-sandbox Jun 2, 2019
4f0bfdb
Allow compilation in multiple translation units
andy-sandbox Jun 2, 2019
ea723d4
Use more informative names
andy-sandbox Jun 2, 2019
9619b2e
Include the max value for power-of-two buffer sizes
andy-sandbox Jun 2, 2019
0086098
Extract methods to make code clearer
andy-sandbox Jun 2, 2019
df8dcb1
Add support for non-timestamped ASIO drivers & 24-bit packed outputs
andy-sandbox Jun 2, 2019
2ef3d8a
Define some sample types & tests
andy-sandbox Jun 3, 2019
3042e02
Move __asio_sample classes to separate header
andy-sandbox Jun 4, 2019
b8ebb91
Templatize __asio_sample
andy-sandbox Jun 4, 2019
0d9615a
Provide template specialization for __asio_sample<packed24_t>
andy-sandbox Jun 4, 2019
a359170
Templatize write function
andy-sandbox Jun 4, 2019
32f7739
Move size var into same scope as RegEnumKey so that full name is alwa…
andy-sandbox Jun 4, 2019
48200db
Remove unnecessary duplication
andy-sandbox Jun 5, 2019
59e981a
Use __asio_sample in read function
andy-sandbox Jun 5, 2019
dc84a56
Templatize read function
andy-sandbox Jun 5, 2019
21fd50c
Support ASIO float types
andy-sandbox Jun 5, 2019
64d4f54
Clarify intent of ASIOChannelInfo initialization
andy-sandbox Jun 5, 2019
3fe73a6
Return false if start is called before client has connected
andy-sandbox Jun 8, 2019
a007996
Do not assert when ASIO::init fails, expected if ASIO device not present
andy-sandbox Jun 9, 2019
da5090e
Rename __asio_backend.h
andy-sandbox Jun 10, 2019
b3fdb8f
Use Guy's template trick to avoid tcb namespace scoping
andy-sandbox Jun 10, 2019
87dc8b7
Use raw string literal for reg key name
andy-sandbox Jun 10, 2019
9056a6f
Reset ASIO back-pointer using optional device pointer
AndySaul Jun 11, 2019
88ec5cb
Add trompeloeil framework & mock-out ASIO driver
andy-sandbox Jun 6, 2019
58ccfd5
Add builder class to encapsulate trompeloeil setup
andy-sandbox Jun 6, 2019
b92ce77
Add tests for number of channels
andy-sandbox Jun 8, 2019
f75abfa
Add tests for buffer sizes
andy-sandbox Jun 8, 2019
39eba30
Set sensible default for ASIOInfo
andy-sandbox Jun 8, 2019
ec35635
Add tests for sample rates
andy-sandbox Jun 8, 2019
457c26e
Add property tests
andy-sandbox Jun 8, 2019
2325541
Return false if start is called before client has connected
andy-sandbox Jun 8, 2019
d0c842a
Add test for legacy playback
andy-sandbox Jun 8, 2019
880db1d
Add test for timestamped playback
andy-sandbox Jun 8, 2019
e7c124c
Add test for ASIO message response
andy-sandbox Jun 8, 2019
d35bb32
Add some syntactic sugar to playback test
andy-sandbox Jun 9, 2019
66d5a26
Add connect method to test fixture
andy-sandbox Jun 9, 2019
7135c2e
Throws exception if connection attempted when already running
andy-sandbox Jun 9, 2019
22fea1d
Add test for legacy record
andy-sandbox Jun 9, 2019
42265ee
Add test for timestamped record
andy-sandbox Jun 9, 2019
50f87b7
Do not throw if ASIO reg key is not read
AndySaul Jun 11, 2019
f7d65cf
Use method name to convey intent
AndySaul Jun 11, 2019
fdb0ab1
Tidy up __asio_device::enumerate
AndySaul Jun 11, 2019
931de46
Add .clang-format file to keep style consistent
AndySaul Jun 11, 2019
2e4ed65
Use template<class> consistently
AndySaul Jun 11, 2019
ceaf996
Use braced initialisation for members consistently
AndySaul Jun 11, 2019
2c95cc6
Rename type
AndySaul Jun 11, 2019
c337979
Apply clang-tidy fixes
andy-sandbox Jun 15, 2019
9f59a9c
Apply clang-tidy fixes
andy-sandbox Jun 15, 2019
bcd100d
Merge remote-tracking branch 'upstream/master'
andy-sandbox Jun 15, 2019
0e38341
Use size_t for loop iteration
andy-sandbox Jun 15, 2019
c9426c1
Merge branch 'master' into asio_backend
andy-sandbox Jun 15, 2019
253cc44
Don't expose Windows max macro to audio clients
andy-sandbox Jun 15, 2019
3c38016
Add null implementation of set_audio_device_list_callback
andy-sandbox Jun 15, 2019
c08eeb3
Use size_t for loop iteration
andy-sandbox Jun 15, 2019
9578429
Remove empty statement
andy-sandbox Jun 15, 2019
24cf0e1
Remove functions that have been removed from API
andy-sandbox Jun 15, 2019
59b2d15
Remove span, it is no longer used in the project
andy-sandbox Jun 15, 2019
2ed7e68
Remove unnecessary temporary
Jun 16, 2019
1fa4a45
Suppress clang-format warnings
Jun 16, 2019
6d044cf
Delete methods removed from specification
Jun 16, 2019
82fe582
Fix clang-tidy warnings
Jun 16, 2019
6551018
Reformat
Jun 16, 2019
c842ce1
Push __asio_sample class into common header
Jun 16, 2019
d0d171b
Push main functions into common header
Jun 16, 2019
42d94df
Consolidate all ASIO code in __asio_backend.h
Jun 16, 2019
54d9b1e
Consolidate all ASIO code into __asio_backend.h
Jun 16, 2019
6b56435
Fix hicpp-signed-bitwise warning rather than suppressing it
AndySaul Jun 16, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---

BasedOnStyle: LLVM

ColumnLimit: 120 # Arbitrary, feel free to adjust locally. 0 to ignore.
PenaltyExcessCharacter: 1 # Softest limit on line length.
ReflowComments: false # Best we don't do this without a consistent length limit.

AlwaysBreakTemplateDeclarations: true

AllowShortFunctionsOnASingleLine: Empty

SpaceAfterTemplateKeyword: false

ConstructorInitializerIndentWidth: 2
ContinuationIndentWidth: 2
IndentWidth: 2

AllowShortCaseLabelsOnASingleLine: true

DerivePointerAlignment: true

IndentCaseLabels: true

BinPackArguments: false
BinPackParameters: false

---
Language: Cpp

...
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.idea
cmake-build*
.DS_Store
/win_build
19 changes: 17 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,21 @@ cmake_minimum_required(VERSION 3.12)
project(libstdaudio)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")

if (MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /WX")
else ()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
endif ()

if (APPLE)
set(CMAKE_EXE_LINKER_FLAGS "-framework CoreAudio")
endif ()

if (MSVC)
set(CMAKE_EXE_LINKER_FLAGS "winmm.lib")
endif ()

include_directories(include)

add_executable(white_noise examples/white_noise.cpp)
Expand All @@ -24,4 +33,10 @@ add_executable(level_meter examples/level_meter.cpp)
add_executable(test
test/test_main.cpp
test/audio_buffer_test.cpp
test/audio_device_test.cpp)
test/audio_device_test.cpp)

if (MSVC)
add_executable(test_asio
test/test_main.cpp
test/asio_test.cpp)
endif ()
8 changes: 4 additions & 4 deletions examples/level_meter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ int main() {

auto& in = *io.input_buffer;

for (int frame = 0; frame < in.size_frames(); ++frame) {
for (int channel = 0; channel < in.size_channels(); ++channel) {
float abs_value = std::abs(in(frame, channel));
for (size_t frame = 0; frame < in.size_frames(); ++frame) {
for (size_t channel = 0; channel < in.size_channels(); ++channel) {
const float abs_value = std::abs(in(frame, channel));

if (abs_value > max_abs_value)
max_abs_value.store(abs_value);
Expand All @@ -45,4 +45,4 @@ int main() {
std::this_thread::sleep_for(std::chrono::milliseconds(250));
std::cout << gain_to_db(max_abs_value.exchange(0)) << " dB\n";
}
}
}
25 changes: 15 additions & 10 deletions examples/melody.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)

#ifdef WIN32
#define _USE_MATH_DEFINES
#endif

#include <cmath>
#include <array>
#include <thread>
#include <atomic>
#include <audio>

// This example app plays a short melody using a simple square wave synthesiser.
Expand All @@ -21,7 +26,7 @@ constexpr float bpm = 260.0;

float note_to_frequency_hz(int note) {
constexpr float pitch_standard_hz = 440.0f;
return pitch_standard_hz * std::pow(2.0f, float(note - 69) / 12.0f);
return pitch_standard_hz * std::pow(2.0f, static_cast<float>(note - 69) / 12.0f);
}

std::atomic<bool> stop = false;
Expand All @@ -30,7 +35,7 @@ struct synthesiser {
float get_next_sample() {
assert (_sample_rate > 0);

_ms_counter += 1000. / _sample_rate;
_ms_counter += 1000.0f / _sample_rate;
if (_ms_counter >= _note_duration_ms) {
_ms_counter = 0;
if (++_current_note_index < notes.size()) {
Expand All @@ -42,8 +47,8 @@ struct synthesiser {
}
}

auto next_sample = std::copysign(0.1f, std::sin(_phase));
_phase = std::fmod(_phase + _delta, 2.0f * float(M_PI));
const auto next_sample = std::copysign(0.1f, std::sin(_phase));
_phase = std::fmod(_phase + _delta, 2.0f * static_cast<float>(M_PI));
return next_sample;
}

Expand All @@ -54,7 +59,7 @@ struct synthesiser {

private:
void update() noexcept {
float frequency_hz = note_to_frequency_hz(notes.at(_current_note_index));
const float frequency_hz = note_to_frequency_hz(notes.at(_current_note_index));
_delta = 2.0f * frequency_hz * static_cast<float>(M_PI / _sample_rate);
}

Expand All @@ -63,7 +68,7 @@ struct synthesiser {
float _phase = 0;
float _ms_counter = 0;
float _note_duration_ms = 60'000.0f / bpm;
int _current_note_index = 0;
size_t _current_note_index = 0;
};


Expand All @@ -75,18 +80,18 @@ int main() {
return 1;

auto synth = synthesiser();
synth.set_sample_rate(float(device->get_sample_rate()));
synth.set_sample_rate(static_cast<float>(device->get_sample_rate()));

device->connect([=](audio_device&, audio_device_io<float>& io) mutable noexcept {
if (!io.output_buffer.has_value())
return;

auto& out = *io.output_buffer;

for (int frame = 0; frame < out.size_frames(); ++frame) {
for (size_t frame = 0; frame < out.size_frames(); ++frame) {
auto next_sample = synth.get_next_sample();

for (int channel = 0; channel < out.size_channels(); ++channel)
for (size_t channel = 0; channel < out.size_channels(); ++channel)
out(frame, channel) = next_sample;
}
});
Expand All @@ -95,4 +100,4 @@ int main() {
while (!stop.load()) {
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
}
}
2 changes: 1 addition & 1 deletion examples/print_devices.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ void print_device_info(const audio_device& d) {
std::cout << "buffer size = " << d.get_buffer_size_frames() << " frames, ";
std::cout << (d.is_input() ? d.get_num_input_channels() : d.get_num_output_channels()) << " channels";
std::cout << (is_default_device(d) ? " [DEFAULT DEVICE]\n" : "\n");
};
}

void print_device_list(const audio_device_list& list) {
for (auto& item : list) {
Expand Down
20 changes: 12 additions & 8 deletions examples/sine_wave.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)

#ifdef WIN32
#define _USE_MATH_DEFINES
#endif

#include <cmath>
#include <thread>
#include <audio>
Expand All @@ -16,25 +20,25 @@ int main() {
if (!device)
return 1;

float frequency_hz = 440.0f;
float delta = 2.0f * frequency_hz * float(M_PI / device->get_sample_rate());
constexpr float frequency_hz = 440.0f;
const float delta = 2.0f * frequency_hz * static_cast<float>(M_PI / device->get_sample_rate());
float phase = 0;

device->connect([=](audio_device& device, audio_device_io<float>& io) mutable noexcept {
device->connect([=](audio_device&, audio_device_io<float>& io) mutable noexcept {
if (!io.output_buffer.has_value())
return;

auto& out = *io.output_buffer;

for (int frame = 0; frame < out.size_frames(); ++frame) {
float next_sample = std::sin(phase);
phase = std::fmod(phase + delta, 2.0f * M_PI);
for (size_t frame = 0; frame < out.size_frames(); ++frame) {
const float next_sample = std::sin(phase);
phase = std::fmod(phase + delta, 2.0f * static_cast<float>(M_PI));

for (int channel = 0; channel < out.size_channels(); ++channel)
for (size_t channel = 0; channel < out.size_channels(); ++channel)
out(frame, channel) = 0.2f * next_sample;
}
});

device->start();
std::this_thread::sleep_for(std::chrono::seconds(5));
}
}
4 changes: 2 additions & 2 deletions examples/white_noise.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ int main() {

auto &out = *io.output_buffer;

for (int frame = 0; frame < out.size_frames(); ++frame)
for (int channel = 0; channel < out.size_channels(); ++channel)
for (size_t frame = 0; frame < out.size_frames(); ++frame)
for (size_t channel = 0; channel < out.size_channels(); ++channel)
out(frame, channel) = white_noise(gen);
});

Expand Down
8 changes: 5 additions & 3 deletions include/__audio_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

#pragma once

#include <cassert>

#include <chrono>

_LIBSTDAUDIO_NAMESPACE_BEGIN
Expand All @@ -30,7 +32,7 @@ class audio_buffer {
_stride(_num_channels),
_is_contiguous(true) {
assert (num_channels <= _max_num_channels);
for (auto i = 0; i < _num_channels; ++i) {
for (index_type i = 0; i < _num_channels; ++i) {
_channels[i] = data + i;
}
}
Expand All @@ -41,12 +43,12 @@ class audio_buffer {
_stride(1),
_is_contiguous(true) {
assert (num_channels <= _max_num_channels);
for (auto i = 0; i < _num_channels; ++i) {
for (index_type i = 0; i < _num_channels; ++i) {
_channels[i] = data + (i * _num_frames);
}
}

audio_buffer(sample_type** data, index_type num_frames, index_type num_channels,ptr_to_ptr_deinterleaved_t)
audio_buffer(sample_type** data, index_type num_frames, index_type num_channels, ptr_to_ptr_deinterleaved_t)
: _num_frames(num_frames),
_num_channels(num_channels),
_stride(1),
Expand Down
6 changes: 2 additions & 4 deletions include/audio
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@

#include <optional>

// TODO: this is a temporary measure until std::span becomes available
#include "cpp/span.hpp"
using namespace TCB_SPAN_NAMESPACE_NAME;

#define _LIBSTDAUDIO_NAMESPACE std::experimental

#define _LIBSTDAUDIO_NAMESPACE_BEGIN namespace _LIBSTDAUDIO_NAMESPACE {
Expand All @@ -21,6 +17,8 @@ using namespace TCB_SPAN_NAMESPACE_NAME;

#ifdef __APPLE__
#include <audio_backend/__coreaudio_backend.h>
#elif defined _WIN32
#include <audio_backend/__asio_backend.h>
#else
#include <audio_backend/__null_backend.h>
#endif // __APPLE__
Loading