Skip to content

Commit 203a104

Browse files
committed
Add clone() method to Sound
1 parent e3d227c commit 203a104

File tree

3 files changed

+52
-1
lines changed

3 files changed

+52
-1
lines changed

include/scratchcpp/sound.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ class LIBSCRATCHCPP_EXPORT Sound : public Asset
3232

3333
virtual bool isPlaying();
3434

35+
std::shared_ptr<Sound> clone() const;
36+
3537
protected:
3638
void processData(unsigned int size, void *data) override;
3739

src/scratch/sound.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,24 @@ bool Sound::isPlaying()
6262
return impl->player->isPlaying();
6363
}
6464

65+
/*! Returns an independent copy of the sound which is valid for as long as the original sound exists. */
66+
std::shared_ptr<Sound> Sound::clone() const
67+
{
68+
auto sound = std::make_shared<Sound>(name(), id(), dataFormat());
69+
sound->setRate(rate());
70+
sound->setSampleCount(sampleCount());
71+
sound->impl->player->loadCopy(impl->player.get());
72+
sound->impl->player->setVolume(impl->player->volume());
73+
sound->setData(dataSize(), const_cast<void *>(data()));
74+
75+
return sound;
76+
}
77+
6578
void Sound::processData(unsigned int size, void *data)
6679
{
80+
if (impl->player->isLoaded())
81+
return;
82+
6783
if (!impl->player->load(size, data, impl->rate))
6884
std::cerr << "Failed to load sound " << name() << std::endl;
6985
}

test/assets/sound_test.cpp

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,12 @@ TEST_F(SoundTest, ProcessData)
6060
const char *data = "abc";
6161
void *dataPtr = const_cast<void *>(static_cast<const void *>(data));
6262

63-
EXPECT_CALL(*m_player, load(3, dataPtr, 44100));
63+
EXPECT_CALL(*m_player, isLoaded()).WillOnce(Return(false));
64+
EXPECT_CALL(*m_player, load(3, dataPtr, 44100)).WillOnce(Return(true));
65+
sound.setData(3, dataPtr);
66+
67+
EXPECT_CALL(*m_player, isLoaded()).WillOnce(Return(true));
68+
EXPECT_CALL(*m_player, load).Times(0);
6469
sound.setData(3, dataPtr);
6570
}
6671

@@ -100,3 +105,31 @@ TEST_F(SoundTest, IsPlaying)
100105

101106
SoundPrivate::audioOutput = nullptr;
102107
}
108+
109+
TEST_F(SoundTest, Clone)
110+
{
111+
Sound sound("sound1", "a", "wav");
112+
sound.setRate(44100);
113+
sound.setSampleCount(10000);
114+
115+
const char *data = "abc";
116+
void *dataPtr = const_cast<void *>(static_cast<const void *>(data));
117+
118+
EXPECT_CALL(*m_player, isLoaded()).WillOnce(Return(false));
119+
EXPECT_CALL(*m_player, load(3, dataPtr, 44100)).WillOnce(Return(true));
120+
sound.setData(3, dataPtr);
121+
122+
auto clonePlayer = std::make_shared<AudioPlayerMock>();
123+
EXPECT_CALL(m_playerFactory, createAudioPlayer()).WillOnce(Return(clonePlayer));
124+
EXPECT_CALL(*clonePlayer, loadCopy(m_player.get())).WillOnce(Return(true));
125+
EXPECT_CALL(*m_player, volume()).WillOnce(Return(0.45));
126+
EXPECT_CALL(*clonePlayer, setVolume(0.45));
127+
EXPECT_CALL(*clonePlayer, isLoaded()).WillOnce(Return(true));
128+
auto clone = sound.clone();
129+
ASSERT_TRUE(clone);
130+
ASSERT_EQ(clone->name(), sound.name());
131+
ASSERT_EQ(clone->id(), sound.id());
132+
ASSERT_EQ(clone->dataFormat(), sound.dataFormat());
133+
ASSERT_EQ(clone->rate(), sound.rate());
134+
ASSERT_EQ(clone->sampleCount(), sound.sampleCount());
135+
}

0 commit comments

Comments
 (0)