audio_stream_mpc.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. #include "audio_stream_mpc.h"
  2. Error AudioStreamMPC::_open_file() {
  3. if (f) {
  4. memdelete(f);
  5. f=NULL;
  6. }
  7. Error err;
  8. f=FileAccess::open(file,FileAccess::READ,&err);
  9. if (err) {
  10. f=NULL;
  11. ERR_FAIL_V(err);
  12. return err;
  13. }
  14. f->seek_end(0);
  15. streamlen=f->get_pos();
  16. f->seek(0);
  17. if (streamlen<=0) {
  18. memdelete(f);
  19. f=NULL;
  20. ERR_FAIL_V(ERR_INVALID_DATA);
  21. }
  22. data_ofs=0;
  23. if (preload) {
  24. data.resize(streamlen);
  25. DVector<uint8_t>::Write w = data.write();
  26. f->get_buffer(&w[0],streamlen);
  27. memdelete(f);
  28. f=NULL;
  29. }
  30. return OK;
  31. }
  32. void AudioStreamMPC::_close_file() {
  33. if (f) {
  34. memdelete(f);
  35. f=NULL;
  36. }
  37. data.resize(0);
  38. streamlen=0;
  39. data_ofs=0;
  40. }
  41. int AudioStreamMPC::_read_file(void *p_dst,int p_bytes) {
  42. if (f)
  43. return f->get_buffer((uint8_t*)p_dst,p_bytes);
  44. DVector<uint8_t>::Read r = data.read();
  45. if (p_bytes+data_ofs > streamlen) {
  46. p_bytes=streamlen-data_ofs;
  47. }
  48. copymem(p_dst,&r[data_ofs],p_bytes);
  49. //print_line("read file: "+itos(p_bytes));
  50. data_ofs+=p_bytes;
  51. return p_bytes;
  52. }
  53. bool AudioStreamMPC::_seek_file(int p_pos){
  54. if (p_pos<0 || p_pos>streamlen)
  55. return false;
  56. if (f) {
  57. f->seek(p_pos);
  58. return true;
  59. }
  60. //print_line("read file to: "+itos(p_pos));
  61. data_ofs=p_pos;
  62. return true;
  63. }
  64. int AudioStreamMPC::_tell_file() const{
  65. if (f)
  66. return f->get_pos();
  67. //print_line("tell file, get: "+itos(data_ofs));
  68. return data_ofs;
  69. }
  70. int AudioStreamMPC::_sizeof_file() const{
  71. //print_line("sizeof file, get: "+itos(streamlen));
  72. return streamlen;
  73. }
  74. bool AudioStreamMPC::_canseek_file() const{
  75. //print_line("canseek file, get true");
  76. return true;
  77. }
  78. /////////////////////
  79. mpc_int32_t AudioStreamMPC::_mpc_read(mpc_reader *p_reader,void *p_dst, mpc_int32_t p_bytes) {
  80. AudioStreamMPC *smpc=(AudioStreamMPC *)p_reader->data;
  81. return smpc->_read_file(p_dst,p_bytes);
  82. }
  83. mpc_bool_t AudioStreamMPC::_mpc_seek(mpc_reader *p_reader,mpc_int32_t p_offset) {
  84. AudioStreamMPC *smpc=(AudioStreamMPC *)p_reader->data;
  85. return smpc->_seek_file(p_offset);
  86. }
  87. mpc_int32_t AudioStreamMPC::_mpc_tell(mpc_reader *p_reader) {
  88. AudioStreamMPC *smpc=(AudioStreamMPC *)p_reader->data;
  89. return smpc->_tell_file();
  90. }
  91. mpc_int32_t AudioStreamMPC::_mpc_get_size(mpc_reader *p_reader) {
  92. AudioStreamMPC *smpc=(AudioStreamMPC *)p_reader->data;
  93. return smpc->_sizeof_file();
  94. }
  95. mpc_bool_t AudioStreamMPC::_mpc_canseek(mpc_reader *p_reader) {
  96. AudioStreamMPC *smpc=(AudioStreamMPC *)p_reader->data;
  97. return smpc->_canseek_file();
  98. }
  99. bool AudioStreamMPC::_can_mix() const {
  100. return /*active &&*/ !paused;
  101. }
  102. void AudioStreamMPC::update() {
  103. if (!active || paused)
  104. return;
  105. int todo=get_todo();
  106. while(todo>MPC_DECODER_BUFFER_LENGTH/si.channels) {
  107. mpc_frame_info frame;
  108. frame.buffer=sample_buffer;
  109. mpc_status err = mpc_demux_decode(demux, &frame);
  110. if (frame.bits!=-1) {
  111. int16_t *dst_buff = get_write_buffer();
  112. #ifdef MPC_FIXED_POINT
  113. for( int i = 0; i < frame.samples * si.channels; i++) {
  114. int tmp = sample_buffer[i] >> MPC_FIXED_POINT_FRACTPART;
  115. if (tmp > ((1 << 15) - 1)) tmp = ((1 << 15) - 1);
  116. if (tmp < -(1 << 15)) tmp = -(1 << 15);
  117. dst_buff[i] = tmp;
  118. }
  119. #else
  120. for( int i = 0; i < frame.samples * si.channels; i++) {
  121. int tmp = Math::fast_ftoi(sample_buffer[i]*32767.0);
  122. if (tmp > ((1 << 15) - 1)) tmp = ((1 << 15) - 1);
  123. if (tmp < -(1 << 15)) tmp = -(1 << 15);
  124. dst_buff[i] = tmp;
  125. }
  126. #endif
  127. int frames = frame.samples;
  128. write(frames);
  129. todo-=frames;
  130. } else {
  131. if (err != MPC_STATUS_OK) {
  132. stop();
  133. ERR_EXPLAIN("Error decoding MPC");
  134. ERR_FAIL();
  135. } else {
  136. //finished
  137. if (!loop) {
  138. stop();
  139. return;
  140. } else {
  141. loops++;
  142. mpc_demux_exit(demux);
  143. _seek_file(0);
  144. demux = mpc_demux_init(&reader);
  145. //do loop somehow
  146. }
  147. }
  148. }
  149. }
  150. }
  151. Error AudioStreamMPC::_reload() {
  152. ERR_FAIL_COND_V(demux!=NULL, ERR_FILE_ALREADY_IN_USE);
  153. Error err = _open_file();
  154. ERR_FAIL_COND_V(err!=OK,ERR_CANT_OPEN);
  155. demux = mpc_demux_init(&reader);
  156. ERR_FAIL_COND_V(!demux,ERR_CANT_CREATE);
  157. mpc_demux_get_info(demux, &si);
  158. _setup(si.channels,si.sample_freq,MPC_DECODER_BUFFER_LENGTH*2/si.channels);
  159. return OK;
  160. }
  161. void AudioStreamMPC::set_file(const String& p_file) {
  162. file=p_file;
  163. }
  164. String AudioStreamMPC::get_file() const {
  165. return file;
  166. }
  167. void AudioStreamMPC::play() {
  168. _THREAD_SAFE_METHOD_
  169. if (active)
  170. stop();
  171. active=false;
  172. Error err = _open_file();
  173. ERR_FAIL_COND(err!=OK);
  174. if (_reload()!=OK)
  175. return;
  176. active=true;
  177. loops=0;
  178. }
  179. void AudioStreamMPC::stop() {
  180. _THREAD_SAFE_METHOD_
  181. if (!active)
  182. return;
  183. if (demux) {
  184. mpc_demux_exit(demux);
  185. demux=NULL;
  186. }
  187. _close_file();
  188. active=false;
  189. }
  190. bool AudioStreamMPC::is_playing() const {
  191. return active || (get_total() - get_todo() -1 > 0);
  192. }
  193. void AudioStreamMPC::set_paused(bool p_paused) {
  194. paused=p_paused;
  195. }
  196. bool AudioStreamMPC::is_paused(bool p_paused) const {
  197. return paused;
  198. }
  199. void AudioStreamMPC::set_loop(bool p_enable) {
  200. loop=p_enable;
  201. }
  202. bool AudioStreamMPC::has_loop() const {
  203. return loop;
  204. }
  205. float AudioStreamMPC::get_length() const {
  206. return 0;
  207. }
  208. String AudioStreamMPC::get_stream_name() const {
  209. return "";
  210. }
  211. int AudioStreamMPC::get_loop_count() const {
  212. return 0;
  213. }
  214. float AudioStreamMPC::get_pos() const {
  215. return 0;
  216. }
  217. void AudioStreamMPC::seek_pos(float p_time) {
  218. }
  219. AudioStream::UpdateMode AudioStreamMPC::get_update_mode() const {
  220. return UPDATE_THREAD;
  221. }
  222. void AudioStreamMPC::_bind_methods() {
  223. ObjectTypeDB::bind_method(_MD("set_file","name"),&AudioStreamMPC::set_file);
  224. ObjectTypeDB::bind_method(_MD("get_file"),&AudioStreamMPC::get_file);
  225. ADD_PROPERTYNZ( PropertyInfo(Variant::STRING,"file",PROPERTY_HINT_FILE,"mpc"), _SCS("set_file"), _SCS("get_file"));
  226. }
  227. AudioStreamMPC::AudioStreamMPC() {
  228. preload=true;
  229. f=NULL;
  230. streamlen=0;
  231. data_ofs=0;
  232. active=false;
  233. paused=false;
  234. loop=false;
  235. demux=NULL;
  236. reader.data=this;
  237. reader.read=_mpc_read;
  238. reader.seek=_mpc_seek;
  239. reader.tell=_mpc_tell;
  240. reader.get_size=_mpc_get_size;
  241. reader.canseek=_mpc_canseek;
  242. loops=0;
  243. }
  244. AudioStreamMPC::~AudioStreamMPC() {
  245. stop();
  246. if (f)
  247. memdelete(f);
  248. }
  249. RES ResourceFormatLoaderAudioStreamMPC::load(const String &p_path,const String& p_original_path) {
  250. AudioStreamMPC *mpc_stream = memnew(AudioStreamMPC);
  251. mpc_stream->set_file(p_path);
  252. return Ref<AudioStreamMPC>(mpc_stream);
  253. }
  254. void ResourceFormatLoaderAudioStreamMPC::get_recognized_extensions(List<String> *p_extensions) const {
  255. p_extensions->push_back("mpc");
  256. }
  257. bool ResourceFormatLoaderAudioStreamMPC::handles_type(const String& p_type) const {
  258. return (p_type=="AudioStream") || (p_type=="AudioStreamMPC");
  259. }
  260. String ResourceFormatLoaderAudioStreamMPC::get_resource_type(const String &p_path) const {
  261. if (p_path.extension().to_lower()=="mpc")
  262. return "AudioStreamMPC";
  263. return "";
  264. }