native_midi.m 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /*
  2. native_midi_android: Native Midi support on iOS for SDLPal
  3. Copyright (C) 2017 Pal Lockheart
  4. This library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public
  6. License as published by the Free Software Foundation; either
  7. version 2 of the License, or (at your option) any later version.
  8. This library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Library General Public License for more details.
  12. You should have received a copy of the GNU Library General Public
  13. License along with this library; if not, write to the Free
  14. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  15. Pal Lockheart
  16. */
  17. #include "SDL_config.h"
  18. #include "SDL.h"
  19. #include "SDL_endian.h"
  20. #include "native_midi/native_midi.h"
  21. #import <Foundation/Foundation.h>
  22. #import <AVFoundation/AVFoundation.h>
  23. #include "palcommon.h"
  24. #include "util.h"
  25. /* Native Midi song */
  26. struct _NativeMidiSong
  27. {
  28. int _placeholder;
  29. int playing;
  30. };
  31. static NativeMidiSong *currentsong = NULL;
  32. static int latched_volume = 128;
  33. static AVMIDIPlayer *midiPlayer;
  34. int native_midi_detect()
  35. {
  36. return 1; /* always available. */
  37. }
  38. NativeMidiSong *native_midi_loadsong(const char *midifile)
  39. {
  40. NativeMidiSong *retval = NULL;
  41. SDL_RWops *rw = SDL_RWFromFile(midifile, "rb");
  42. if (rw != NULL) {
  43. retval = native_midi_loadsong_RW(rw);
  44. SDL_RWclose(rw);
  45. }
  46. return retval;
  47. }
  48. NativeMidiSong *native_midi_loadsong_RW(SDL_RWops *rw)
  49. {
  50. NativeMidiSong *retval = (NativeMidiSong *)malloc(sizeof(NativeMidiSong));
  51. char midiInterFile[PATH_MAX];
  52. snprintf(midiInterFile, PATH_MAX, "%s%s", [NSTemporaryDirectory() UTF8String], "inter.mid");
  53. FILE *fp = fopen(midiInterFile, "wb+");
  54. if (fp)
  55. {
  56. char buf[4096];
  57. size_t bytes;
  58. while((bytes = SDL_RWread(rw, buf, sizeof(char), sizeof(buf)))!=0)
  59. fwrite(buf, sizeof(char), bytes, fp);
  60. fclose(fp);
  61. memset(retval, 0, sizeof(NativeMidiSong));
  62. NSURL *midiFileURL = [NSURL URLWithString:[NSString stringWithUTF8String:midiInterFile]];
  63. NSURL *bankURL = [[NSBundle mainBundle] URLForResource:@"gs_instruments" withExtension: @"dls"];
  64. if( midiPlayer ) {
  65. [midiPlayer dealloc];
  66. midiPlayer = nil;
  67. }
  68. NSError *err=nil;
  69. midiPlayer = [[AVMIDIPlayer new] initWithContentsOfURL:midiFileURL soundBankURL:bankURL error:&err];
  70. [midiPlayer prepareToPlay];
  71. }
  72. return retval;
  73. }
  74. void native_midi_freesong(NativeMidiSong *song)
  75. {
  76. if (song != NULL)
  77. {
  78. native_midi_stop(song);
  79. if (currentsong == song)
  80. currentsong = NULL;
  81. free(song);
  82. if( midiPlayer ) {
  83. [midiPlayer dealloc];
  84. midiPlayer = nil;
  85. }
  86. }
  87. }
  88. void native_midi_start(NativeMidiSong *song, int looping)
  89. {
  90. native_midi_stop(song);
  91. if (song != NULL)
  92. {
  93. currentsong = song;
  94. currentsong->playing = 1;
  95. [midiPlayer play:^(){
  96. if( currentsong ) {
  97. midiPlayer.currentPosition = 0;
  98. native_midi_start(currentsong,looping);
  99. }
  100. }];
  101. }
  102. }
  103. void native_midi_stop()
  104. {
  105. if (currentsong) {
  106. currentsong->playing = 0;
  107. [midiPlayer stop];
  108. }
  109. }
  110. int native_midi_active()
  111. {
  112. return currentsong ? currentsong->playing : 0;
  113. }
  114. void native_midi_setvolume(NativeMidiSong *song, int volume)
  115. {
  116. }
  117. const char *native_midi_error(NativeMidiSong *song)
  118. {
  119. return ""; /* !!! FIXME */
  120. }