gibberish_stream.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. /*************************************************************************/
  2. /* gibberish_stream.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* http://www.godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  9. /* */
  10. /* Permission is hereby granted, free of charge, to any person obtaining */
  11. /* a copy of this software and associated documentation files (the */
  12. /* "Software"), to deal in the Software without restriction, including */
  13. /* without limitation the rights to use, copy, modify, merge, publish, */
  14. /* distribute, sublicense, and/or sell copies of the Software, and to */
  15. /* permit persons to whom the Software is furnished to do so, subject to */
  16. /* the following conditions: */
  17. /* */
  18. /* The above copyright notice and this permission notice shall be */
  19. /* included in all copies or substantial portions of the Software. */
  20. /* */
  21. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  22. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  23. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  24. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  25. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  26. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  27. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  28. /*************************************************************************/
  29. #include "gibberish_stream.h"
  30. #include "servers/audio_server.h"
  31. int AudioStreamGibberish::get_channel_count() const {
  32. return 1;
  33. }
  34. static float _get_vol_at_pos(int p_pos, int p_len, int p_x_fade) {
  35. if (p_pos < p_x_fade)
  36. return float(p_pos)/p_x_fade;
  37. else if (p_pos>(p_len-p_x_fade))
  38. return float(p_len-p_pos)/p_x_fade;
  39. else
  40. return 1.0;
  41. }
  42. int AudioStreamGibberish::randomize() {
  43. if (rand_idx==_rand_pool.size()) {
  44. for(int i=0;i<_rand_pool.size();i++) {
  45. SWAP(_rand_pool[i],_rand_pool[Math::rand()%_rand_pool.size()]);
  46. }
  47. rand_idx=0;
  48. }
  49. return _rand_pool[rand_idx++];
  50. }
  51. bool AudioStreamGibberish::mix(int32_t *p_buffer, int p_frames) {
  52. if (!active)
  53. return false;
  54. zeromem(p_buffer,p_frames*sizeof(int32_t));
  55. if (!paused && active_voices==0) {
  56. active_voices=1;
  57. playback[0].idx=randomize();
  58. playback[0].fp_pos=0;
  59. playback[0].scale=Math::random(1,1+pitch_random_scale);
  60. }
  61. for(int i=0;i<active_voices;i++) {
  62. RID s = _samples[playback[i].idx]->get_rid();
  63. uint64_t fp_pos=playback[i].fp_pos;
  64. const void *data = AudioServer::get_singleton()->sample_get_data_ptr(s);
  65. bool is16 = AudioServer::get_singleton()->sample_get_format(s)==AudioServer::SAMPLE_FORMAT_PCM16;
  66. int skip = AudioServer::get_singleton()->sample_is_stereo(s) ? 1: 0;
  67. uint64_t max = AudioServer::get_singleton()->sample_get_length(s) * uint64_t(FP_LEN);
  68. int mrate = AudioServer::get_singleton()->sample_get_mix_rate(s) * pitch_scale * playback[i].scale;
  69. uint64_t increment = uint64_t(mrate) * uint64_t(FP_LEN) / get_mix_rate();
  70. float vol_begin = _get_vol_at_pos(fp_pos>>FP_BITS,max>>FP_BITS,xfade_time*mrate);
  71. float vol_end = _get_vol_at_pos((fp_pos+p_frames*increment)>>FP_BITS,max>>FP_BITS,xfade_time*mrate);
  72. int32_t vol = CLAMP(int32_t(vol_begin * 65535),0,65535);
  73. int32_t vol_to = CLAMP(int32_t(vol_end * 65535),0,65535);
  74. int32_t vol_inc = (vol_to-vol)/p_frames;
  75. bool done=false;
  76. if (is16) {
  77. const int16_t *smp = (int16_t*)data;
  78. for(int i=0;i<p_frames;i++) {
  79. if (fp_pos >= max) {
  80. done=true;
  81. break;
  82. }
  83. int idx = (fp_pos>>FP_BITS)<<skip;
  84. p_buffer[i]+=int32_t(smp[idx])*vol;
  85. vol+=vol_inc;
  86. fp_pos+=increment;
  87. }
  88. } else {
  89. const int8_t *smp = (int8_t*)data;
  90. for(int i=0;i<p_frames;i++) {
  91. if (fp_pos >= max) {
  92. done=true;
  93. break;
  94. }
  95. int idx = (fp_pos>>FP_BITS)<<skip;
  96. p_buffer[i]+=(int32_t(smp[idx])<<8)*vol;
  97. vol+=vol_inc;
  98. fp_pos+=increment;
  99. }
  100. }
  101. playback[i].fp_pos=fp_pos;
  102. if (!paused && active_voices==1 && (vol_end < vol_begin || done)) {
  103. //xfade to something else i gues
  104. active_voices=2;
  105. playback[1].idx=randomize();
  106. playback[1].fp_pos=0;
  107. playback[1].scale=Math::random(1,1+pitch_random_scale);
  108. }
  109. if (done) {
  110. if (i==0 && active_voices==2) {
  111. playback[0]=playback[1];
  112. i--;
  113. }
  114. active_voices--;
  115. }
  116. }
  117. return true;
  118. }
  119. void AudioStreamGibberish::play() {
  120. if (active)
  121. stop();
  122. if (!phonemes.is_valid())
  123. return;
  124. List<StringName> slist;
  125. phonemes->get_sample_list(&slist);
  126. if (slist.size()==0)
  127. return;
  128. _samples.resize(slist.size());
  129. _rand_pool.resize(slist.size());
  130. int i=0;
  131. for(List<StringName>::Element *E=slist.front();E;E=E->next()) {
  132. _rand_pool[i]=i;
  133. _samples[i++]=phonemes->get_sample(E->get());
  134. }
  135. rand_idx=0;
  136. active_voices=0;
  137. active=true;
  138. }
  139. void AudioStreamGibberish::stop(){
  140. active=false;
  141. }
  142. bool AudioStreamGibberish::is_playing() const {
  143. return active;
  144. }
  145. void AudioStreamGibberish::set_paused(bool p_paused){
  146. paused=p_paused;
  147. }
  148. bool AudioStreamGibberish::is_paused(bool p_paused) const{
  149. return paused;
  150. }
  151. void AudioStreamGibberish::set_loop(bool p_enable){
  152. }
  153. bool AudioStreamGibberish::has_loop() const{
  154. return false;
  155. }
  156. float AudioStreamGibberish::get_length() const{
  157. return 0;
  158. }
  159. String AudioStreamGibberish::get_stream_name() const{
  160. return "Gibberish";
  161. }
  162. int AudioStreamGibberish::get_loop_count() const{
  163. return 0;
  164. }
  165. float AudioStreamGibberish::get_pos() const{
  166. return 0;
  167. }
  168. void AudioStreamGibberish::seek_pos(float p_time){
  169. }
  170. AudioStream::UpdateMode AudioStreamGibberish::get_update_mode() const{
  171. return AudioStream::UPDATE_NONE;
  172. }
  173. void AudioStreamGibberish::update(){
  174. }
  175. void AudioStreamGibberish::set_phonemes(const Ref<SampleLibrary>& p_phonemes) {
  176. phonemes=p_phonemes;
  177. }
  178. Ref<SampleLibrary> AudioStreamGibberish::get_phonemes() const {
  179. return phonemes;
  180. }
  181. void AudioStreamGibberish::set_xfade_time(float p_xfade) {
  182. xfade_time=p_xfade;
  183. }
  184. float AudioStreamGibberish::get_xfade_time() const {
  185. return xfade_time;
  186. }
  187. void AudioStreamGibberish::set_pitch_scale(float p_scale) {
  188. pitch_scale=p_scale;
  189. }
  190. float AudioStreamGibberish::get_pitch_scale() const {
  191. return pitch_scale;
  192. }
  193. void AudioStreamGibberish::set_pitch_random_scale(float p_random_scale) {
  194. pitch_random_scale=p_random_scale;
  195. }
  196. float AudioStreamGibberish::get_pitch_random_scale() const {
  197. return pitch_random_scale;
  198. }
  199. void AudioStreamGibberish::_bind_methods() {
  200. ObjectTypeDB::bind_method(_MD("set_phonemes","phonemes"),&AudioStreamGibberish::set_phonemes);
  201. ObjectTypeDB::bind_method(_MD("get_phonemes"),&AudioStreamGibberish::get_phonemes);
  202. ObjectTypeDB::bind_method(_MD("set_pitch_scale","pitch_scale"),&AudioStreamGibberish::set_pitch_scale);
  203. ObjectTypeDB::bind_method(_MD("get_pitch_scale"),&AudioStreamGibberish::get_pitch_scale);
  204. ObjectTypeDB::bind_method(_MD("set_pitch_random_scale","pitch_random_scale"),&AudioStreamGibberish::set_pitch_random_scale);
  205. ObjectTypeDB::bind_method(_MD("get_pitch_random_scale"),&AudioStreamGibberish::get_pitch_random_scale);
  206. ObjectTypeDB::bind_method(_MD("set_xfade_time","sec"),&AudioStreamGibberish::set_xfade_time);
  207. ObjectTypeDB::bind_method(_MD("get_xfade_time"),&AudioStreamGibberish::get_xfade_time);
  208. ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"phonemes",PROPERTY_HINT_RESOURCE_TYPE,"SampleLibrary"),_SCS("set_phonemes"),_SCS("get_phonemes"));
  209. ADD_PROPERTY( PropertyInfo(Variant::REAL,"pitch_scale",PROPERTY_HINT_RANGE,"0.01,64,0.01"),_SCS("set_pitch_scale"),_SCS("get_pitch_scale"));
  210. ADD_PROPERTY( PropertyInfo(Variant::REAL,"pitch_random_scale",PROPERTY_HINT_RANGE,"0,64,0.01"),_SCS("set_pitch_random_scale"),_SCS("get_pitch_random_scale"));
  211. ADD_PROPERTY( PropertyInfo(Variant::REAL,"xfade_sec",PROPERTY_HINT_RANGE,"0.001,0.5,0.001"),_SCS("set_xfade_time"),_SCS("get_xfade_time"));
  212. }
  213. AudioStreamGibberish::AudioStreamGibberish() {
  214. xfade_time=0.1;
  215. pitch_scale=1;
  216. pitch_random_scale=0;
  217. active=false;
  218. paused=false;
  219. active_voices=0;
  220. }