SHOW:
|
|
- or go back to the newest paste.
1 | #include "CustomMusicPlayer.h" | |
2 | #include "MusicPlayerActor.h" | |
3 | ||
4 | //#define DEBUG_MUSIC_PLAYER_ACTOR 1 | |
5 | ||
6 | AMusicPlayerActor::AMusicPlayerActor(const class FPostConstructInitializeProperties& PCIP) | |
7 | : Super(PCIP) | |
8 | { | |
9 | FileName = "My Song.ogg"; | |
10 | ||
11 | Box_play = PCIP.CreateDefaultSubobject<UBoxComponent>(this, TEXT("box_play")); | |
12 | light_play = PCIP.CreateDefaultSubobject<UPointLightComponent>(this, TEXT("light_play")); | |
13 | Box_pause = PCIP.CreateDefaultSubobject<UBoxComponent>(this, TEXT("box_pause")); | |
14 | light_stop = PCIP.CreateDefaultSubobject<UPointLightComponent>(this, TEXT("light_stop")); | |
15 | Box_stop = PCIP.CreateDefaultSubobject<UBoxComponent>(this, TEXT("box_stop")); | |
16 | light_pause = PCIP.CreateDefaultSubobject<UPointLightComponent>(this, TEXT("light_pause")); | |
17 | ||
18 | RootComponent = Box_play; | |
19 | Box_pause->AttachTo(RootComponent); | |
20 | Box_stop->AttachTo(RootComponent); | |
21 | ||
22 | light_play->Intensity = 10000; | |
23 | light_play->SetLightColor(FColor::Green); | |
24 | light_play->AttachTo(RootComponent); | |
25 | light_stop->Intensity = 10000; | |
26 | light_stop->SetLightColor(FColor::Red); | |
27 | light_stop->AttachTo(Box_stop); | |
28 | light_pause->Intensity = 10000; | |
29 | light_pause->SetLightColor(FColor::Yellow); | |
30 | light_pause->AttachTo(Box_pause); | |
31 | ||
32 | Box_play->bGenerateOverlapEvents = true; | |
33 | Box_pause->bGenerateOverlapEvents = true; | |
34 | Box_stop->bGenerateOverlapEvents = true; | |
35 | ||
36 | Box_stop->AddRelativeLocation(FVector(75, 0, 0)); | |
37 | Box_pause->AddRelativeLocation(FVector(-75, 0, 0)); | |
38 | ||
39 | Box_play->SetRelativeScale3D(FVector(5, 5, 5)); | |
40 | ||
41 | Box_play->OnComponentBeginOverlap.AddDynamic(this, &AMusicPlayerActor::TriggerEnter); | |
42 | Box_play->OnComponentEndOverlap.AddDynamic(this, &AMusicPlayerActor::TriggerExit); | |
43 | Box_pause->OnComponentBeginOverlap.AddDynamic(this, &AMusicPlayerActor::TriggerEnterPause); | |
44 | Box_pause->OnComponentEndOverlap.AddDynamic(this, &AMusicPlayerActor::TriggerExitPause); | |
45 | Box_stop->OnComponentBeginOverlap.AddDynamic(this, &AMusicPlayerActor::TriggerEnterStop); | |
46 | Box_stop->OnComponentEndOverlap.AddDynamic(this, &AMusicPlayerActor::TriggerExitStop); | |
47 | ||
48 | sw = (USoundWave*)StaticConstructObject(USoundWave::StaticClass(), this, TEXT("MyTestSoundWave")); | |
49 | ac = PCIP.CreateDefaultSubobject<UAudioComponent>(this, TEXT("audio_component")); | |
50 | device = GEngine ? GEngine->GetAudioDevice() : NULL; //gently ask for the audio device | |
51 | ||
52 | sw->SoundGroup = ESoundGroup::SOUNDGROUP_Music; | |
53 | ac->bIsUISound = true; | |
54 | ac->bIsMusic = true; | |
55 | ac->bAutoActivate = false; | |
56 | ||
57 | loaded = false; | |
58 | } | |
59 | ||
60 | inline void AMusicPlayerActor::Load(FString NewFileName = "") | |
61 | { | |
62 | if (NewFileName != "") | |
63 | { | |
64 | FileName = NewFileName; | |
65 | Stop(); | |
66 | } | |
67 | loaded = FFileHelper::LoadFileToArray(rawFile, FileName.GetCharArray().GetTypedData()); | |
68 | ||
69 | if (loaded){ | |
70 | Debug("loaded"); | |
71 | ||
72 | FByteBulkData* bulkData = &sw->CompressedFormatData.GetFormat(TEXT("OGG")); | |
73 | bulkData->Lock(LOCK_READ_WRITE); | |
74 | FMemory::Memcpy(bulkData->Realloc(rawFile.Num()), rawFile.GetTypedData(), rawFile.Num()); | |
75 | bulkData->Unlock(); | |
76 | fillSoundWaveInfo(sw, &rawFile); | |
77 | ac->SetSound(sw); | |
78 | } | |
79 | } | |
80 | ||
81 | void AMusicPlayerActor::Play() | |
82 | { | |
83 | if (!loaded){ | |
84 | Load(); | |
85 | } | |
86 | if (!loaded){ | |
87 | return; | |
88 | } | |
89 | ||
90 | if (isPaused){ | |
91 | audioSource->Play(); | |
92 | isPaused = false; | |
93 | } | |
94 | else | |
95 | { | |
96 | ac->Play(); | |
97 | } | |
98 | } | |
99 | ||
100 | void AMusicPlayerActor::Pause() | |
101 | { | |
102 | int status = findSource(sw); | |
103 | //Debug("Surce location returned " + FString::FromInt(status)); | |
104 | ||
105 | if (audioSource) | |
106 | { | |
107 | audioSource->Pause(); | |
108 | isPaused = true; | |
109 | } | |
110 | } | |
111 | ||
112 | void AMusicPlayerActor::Stop() | |
113 | { | |
114 | ac->Stop(); | |
115 | isPaused = false; | |
116 | if (audioSource) | |
117 | { | |
118 | audioSource->Stop(); | |
119 | } | |
120 | } | |
121 | ||
122 | void AMusicPlayerActor::TriggerEnter(class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex) | |
123 | { | |
124 | //Debug("trigger play enter"); | |
125 | Play(); | |
126 | } | |
127 | ||
128 | void AMusicPlayerActor::TriggerExit(class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex) | |
129 | { | |
130 | ||
131 | //Debug("trigger play exit"); | |
132 | } | |
133 | ||
134 | void AMusicPlayerActor::TriggerEnterPause(class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex) | |
135 | { | |
136 | //Debug("trigger pause enter"); | |
137 | Pause(); | |
138 | } | |
139 | ||
140 | void AMusicPlayerActor::TriggerExitPause(class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex) | |
141 | { | |
142 | //Debug("trigger pause exit"); | |
143 | } | |
144 | ||
145 | void AMusicPlayerActor::TriggerEnterStop(class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex) | |
146 | { | |
147 | //Debug("trigger stop enter"); | |
148 | Stop(); | |
149 | } | |
150 | ||
151 | void AMusicPlayerActor::TriggerExitStop(class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex) | |
152 | { | |
153 | //Debug("trigger stop exit"); | |
154 | ||
155 | } | |
156 | ||
157 | int AMusicPlayerActor::fillSoundWaveInfo(USoundWave* sw, TArray<uint8>* rawFile) | |
158 | { | |
159 | FSoundQualityInfo info; | |
160 | FVorbisAudioInfo vorbis_obj = FVorbisAudioInfo(); | |
161 | if (!vorbis_obj.ReadCompressedInfo(rawFile->GetTypedData(), rawFile->Num(), &info)) | |
162 | { | |
163 | //Debug("Can't load header"); | |
164 | return 1; | |
165 | } | |
166 | sw->NumChannels = info.NumChannels; | |
167 | sw->Duration = info.Duration; | |
168 | sw->RawPCMDataSize = info.SampleDataSize; | |
169 | sw->SampleRate = info.SampleRate; | |
170 | return 0; | |
171 | } | |
172 | ||
173 | int AMusicPlayerActor::findSource(USoundWave* sw) | |
174 | { | |
175 | if (!device) | |
176 | { | |
177 | activeSound = NULL; | |
178 | audioSource = NULL; | |
179 | return -1; | |
180 | } | |
181 | TArray<FActiveSound*> tmpActualSounds = device->GetActiveSounds(); | |
182 | if (tmpActualSounds.Num()){ | |
183 | for (auto activeSoundIt(tmpActualSounds.CreateIterator()); activeSoundIt; ++activeSoundIt){ | |
184 | activeSound = *activeSoundIt; | |
185 | for (auto WaveInstanceIt(activeSound->WaveInstances.CreateIterator()); WaveInstanceIt; ++WaveInstanceIt){ | |
186 | sw_instance = WaveInstanceIt.Value(); | |
187 | if (sw_instance->WaveData->CompressedDataGuid == sw->CompressedDataGuid){ | |
188 | audioSource = device->WaveInstanceSourceMap.FindRef(sw_instance); | |
189 | return 0; | |
190 | } | |
191 | } | |
192 | } | |
193 | } | |
194 | audioSource = NULL; | |
195 | activeSound = NULL; | |
196 | return -2; | |
197 | } | |
198 | ||
199 | void AMusicPlayerActor::Debug(FString msg){ | |
200 | #ifdef DEBUG_MUSIC_PLAYER_ACTOR | |
201 | if (GEngine){ | |
202 | GEngine->AddOnScreenDebugMessage(-1, 1, FColor::Red, msg); | |
203 | } | |
204 | #endif | |
205 | } |