Skip to content

Commit e64d17e

Browse files
authored
PCMSound utility functions | makeMono | makeStereo | append (#272)
* update README * PCMSound makeMono, makeStereo, append * code rev * add test * code rev * code rev * update version
1 parent 5d3e039 commit e64d17e

File tree

11 files changed

+208
-13
lines changed

11 files changed

+208
-13
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ if(DEFINED ENV{VCPKG_ROOT} AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)
55
endif()
66

77

8-
project ("sdl2-hyper-sonic-drivers" VERSION 0.13.4 DESCRIPTION "SDL2 based Hyper-Sonic Drivers for emulating old soundcards")
8+
project ("sdl2-hyper-sonic-drivers" VERSION 0.14.0 DESCRIPTION "SDL2 based Hyper-Sonic Drivers for emulating old soundcards")
99
include (TestBigEndian)
1010
TEST_BIG_ENDIAN(IS_BIG_ENDIAN)
1111
if(IS_BIG_ENDIAN)

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ At the moment the only implemented emulators are OPL chips.
5656
### Adlib/Sound Blaster PRO 2.0 chips
5757

5858
- [x] Mame OPL2
59-
- [x] Mame OPL3
59+
- [ ] Mame OPL3
6060
- [x] DosBox OPL2
6161
- [x] DosBox Dual OPL2
6262
- [x] DosBox OPL3

sdl2-hyper-sonic-drivers/CMakeLists.txt

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ target_sources(${LIB_NAME} PRIVATE
177177
${CMAKE_CURRENT_SOURCE_DIR}/src/HyperSonicDrivers/utils/constants.cpp
178178
${CMAKE_CURRENT_SOURCE_DIR}/src/HyperSonicDrivers/utils/endianness.cpp
179179
${CMAKE_CURRENT_SOURCE_DIR}/src/HyperSonicDrivers/utils/opl.cpp
180+
${CMAKE_CURRENT_SOURCE_DIR}/src/HyperSonicDrivers/utils/sound.cpp
180181
# --- #
181182
${CMAKE_CURRENT_SOURCE_DIR}/src/HyperSonicDrivers/utils/ILogger.cpp
182183
${CMAKE_CURRENT_SOURCE_DIR}/src/HyperSonicDrivers/utils/sdl2/Logger.cpp
@@ -211,14 +212,7 @@ unset(LIB_VER)
211212

212213
# Add source to this project's executable.
213214
add_executable(sdl2-hyper-sonic-drivers "sdl2-hyper-sonic-drivers.cpp")
214-
#target_sources(sdl2-sonic-drivers PUBLIC
215-
# --- #
216-
#${CMAKE_CURRENT_SOURCE_DIR}/src/files/IFFFile.cpp
217-
#${CMAKE_CURRENT_SOURCE_DIR}/src/files/XMIFile.cpp
218-
#${CMAKE_CURRENT_SOURCE_DIR}/src/files/MIDFile.cpp
219-
#)
220-
221-
target_link_libraries(sdl2-hyper-sonic-drivers PRIVATE ${LIB_SDL2main} hyper-sonic-drivers-static)
215+
target_link_libraries(sdl2-hyper-sonic-drivers PRIVATE ${LIB_SDL2main} hyper-sonic-drivers-static)
222216

223217
if(MSVC)
224218
# @see https://docs.microsoft.com/en-us/cpp/build/reference/compiler-options-listed-by-category?view=vs-2019

sdl2-hyper-sonic-drivers/sdl2-hyper-sonic-drivers.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// TODO: delete this file and its target, this is kinda scratch pad
33

44
#include <iostream>
5+
#include <memory>
56

67
#include <SDL2/SDL.h>
78

@@ -32,6 +33,11 @@
3233
#include <mt32emu/c_interface/cpp_interface.h>
3334
#include <HyperSonicDrivers/hardware/mt32/MT32.hpp>
3435

36+
#include <HyperSonicDrivers/utils/sound.hpp>
37+
#include <HyperSonicDrivers/drivers/PCMDriver.hpp>
38+
#include <HyperSonicDrivers/audio/PCMSound.hpp>
39+
40+
3541
using namespace std;
3642
using namespace HyperSonicDrivers;
3743

@@ -383,6 +389,27 @@ void testMT32()
383389
// utils::delayMillis(1000);
384390
}
385391

392+
393+
void pcm_sound_append()
394+
{
395+
auto mixer = audio::make_mixer<audio::sdl2::Mixer>(8, 44100, 1024);
396+
files::WAVFile w1("test/fixtures/test_renderer_adlib_mame2.wav");
397+
398+
mixer->init();
399+
auto s1 = w1.getSound();
400+
auto s1b = w1.getSound();
401+
//auto s2a = utils::makeMono(s1);
402+
//auto s2b = utils::makeStereo(s1);
403+
auto s2 = utils::append(s1, s1);
404+
drivers::PCMDriver drv(mixer);
405+
406+
drv.play(s2);
407+
while (drv.isPlaying())
408+
{
409+
utils::delayMillis(100);
410+
}
411+
}
412+
386413
int main(int argc, char* argv[])
387414
{
388415
//newMixerTest();
@@ -391,6 +418,8 @@ int main(int argc, char* argv[])
391418
//rendererMIDI();
392419
//midi_adlib();
393420
//testMT32();
421+
422+
pcm_sound_append();
394423
return 0;
395424
//sdlMixer();
396425
//SDL_Delay(100);

sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/audio/PCMSound.hpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ namespace HyperSonicDrivers::audio
1818
PCMSound(PCMSound&) = delete;
1919
PCMSound(PCMSound&&) = delete;
2020
PCMSound& operator=(PCMSound&) = delete;
21+
2122
PCMSound(
2223
const mixer::eChannelGroup group,
2324
const bool isStereo,
@@ -26,10 +27,12 @@ namespace HyperSonicDrivers::audio
2627
const std::shared_ptr<int16_t[]> &data
2728
);
2829

30+
bool append(const PCMSound* sound2) noexcept;
31+
2932
const mixer::eChannelGroup group;
3033
const bool stereo;
3134
const uint32_t freq;
32-
uint32_t dataSize;
33-
std::shared_ptr<int16_t[]> data;
35+
const uint32_t dataSize;
36+
const std::shared_ptr<int16_t[]> data;
3437
};
3538
}

sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/drivers/PCMDriver.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ namespace HyperSonicDrivers::drivers
3434
void stop(const std::shared_ptr<audio::PCMSound>& sound, const bool releaseEndedStreams = true);
3535
void stop() noexcept;
3636

37-
3837
const uint8_t max_streams;
3938
private:
4039
std::shared_ptr<audio::IMixer> m_mixer;

sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/utils/algorithms.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ namespace HyperSonicDrivers::utils
9292
/// wrapper, helper function
9393
/// </summary>
9494
std::string chars_vector_to_string(const std::vector<uint8_t>& e);
95+
9596
/// <summary>
9697
/// Skip first char
9798
/// </summary>
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#include <cstdint>
2+
#include <HyperSonicDrivers/utils/sound.hpp>
3+
#include <HyperSonicDrivers/audio/converters/LinearRateConverter.hpp>
4+
5+
namespace HyperSonicDrivers::utils
6+
{
7+
std::shared_ptr<audio::PCMSound> makeMono(const std::shared_ptr<audio::PCMSound>& sound)
8+
{
9+
if (!sound->stereo)
10+
return sound;
11+
12+
const uint32_t monoDataSize = sound->dataSize / 2;
13+
14+
auto monoData = std::make_shared<int16_t[]>(monoDataSize);
15+
for (uint32_t i = 0, j = 0; i < sound->dataSize; i += 2, j++)
16+
{
17+
monoData[j] = (sound->data[i] + sound->data[i + 1]) / 2;
18+
}
19+
20+
return std::make_shared<audio::PCMSound>(sound->group, false, sound->freq, monoDataSize, monoData);
21+
}
22+
23+
std::shared_ptr<audio::PCMSound> makeStereo(const std::shared_ptr<audio::PCMSound>& sound)
24+
{
25+
if (sound->stereo)
26+
return sound;
27+
28+
const uint32_t stereoDataSize = sound->dataSize * 2;
29+
auto stereoData = std::make_shared<int16_t[]>(stereoDataSize);
30+
for (uint32_t i = 0, j = 0; i < sound->dataSize; i++, j += 2)
31+
{
32+
stereoData[j] = stereoData[j + 1] = sound->data[i];
33+
}
34+
35+
return std::make_shared<audio::PCMSound>(sound->group, true, sound->freq, stereoDataSize, stereoData);
36+
}
37+
38+
std::shared_ptr<audio::PCMSound> append(
39+
const std::shared_ptr<audio::PCMSound>& sound1,
40+
const std::shared_ptr<audio::PCMSound>& sound2)
41+
{
42+
std::shared_ptr<audio::PCMSound> s2;
43+
44+
if (sound1->stereo)
45+
s2 = makeStereo(sound2);
46+
else
47+
s2 = makeMono(sound2);
48+
49+
if (sound1->freq != sound2->freq)
50+
{
51+
// TODO:
52+
// use covert frequency/ sample rate libraries for this ?
53+
utils::throwLogC<std::runtime_error>("different frequency, not implemented yet");
54+
}
55+
56+
const uint32_t dataSize = sound1->dataSize + s2->dataSize;
57+
auto data = std::make_shared<int16_t[]>(dataSize);
58+
59+
memcpy(data.get(), sound1->data.get(), sound1->dataSize * sizeof(int16_t));
60+
memcpy(&data[sound1->dataSize], s2->data.get(), s2->dataSize * sizeof(int16_t));
61+
62+
return std::make_shared<audio::PCMSound>(sound1->group, sound1->stereo, sound1->freq, dataSize, data);
63+
}
64+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#pragma once
2+
3+
#include <memory>
4+
#include <HyperSonicDrivers/audio/PCMSound.hpp>
5+
6+
namespace HyperSonicDrivers::utils
7+
{
8+
/**
9+
* @returns a new mono PCMSound if the parameter is stereo
10+
* otherwise returns the parameter itself.
11+
**/
12+
std::shared_ptr<audio::PCMSound> makeMono(const std::shared_ptr<audio::PCMSound>& sound);
13+
14+
/**
15+
* @returns a new stereo PCMSound if the parameter is mono
16+
* otherwise returns the parameter itself.
17+
**/
18+
std::shared_ptr<audio::PCMSound> makeStereo(const std::shared_ptr<audio::PCMSound>& sound);
19+
20+
/**
21+
* @returns sound1 + sound2.
22+
* it converts sound2 to the same freq and mono/stereo of sound1
23+
**/
24+
std::shared_ptr<audio::PCMSound> append(
25+
const std::shared_ptr<audio::PCMSound>& sound1,
26+
const std::shared_ptr<audio::PCMSound>& sound2);
27+
}

sdl2-hyper-sonic-drivers/test/HyperSonicDrivers/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,12 @@ macro_test(
7373
LINKS_PRIVATE hyper-sonic-drivers-static
7474
)
7575

76+
macro_test(
77+
EXE TestSound
78+
FILES "utils/TestSound.cpp"
79+
LINKS_PRIVATE hyper-sonic-drivers-static
80+
)
81+
7682
macro_test(
7783
EXE TestPCSpeaker
7884
FILES "hardware/TestPCSpeaker.cpp"

0 commit comments

Comments
 (0)