News:

Simutrans Wiki Manual
The official on-line manual for Simutrans. Read and contribute.

Port CoreAudio code to AVFoundation (OS X)

Started by mstea, February 12, 2017, 05:48:18 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

mstea

Apple deprecated QTKit several OS X releases ago, and have stopped including support for it at all as of 10.12. Unfortunately, this means Simutrans can't be built on the latest OS X/Xcode versions. :( This patch ports the QTKit code to use AVFoundation, which is available as of OS X 10.7+. I've tested, and this works fine.

THLeaderH

I DO argue that this patch should be included as soon as possible.

Since macOS Sierra was released September last year, Simutrans code cannot be compiled without some tricky modification including changing MAKEFILE for more than a half year ago! This is because Sierra abolished QTKit, which is needed to play midi and wav.
However, this patch loses the volume control of MIDI. This is because AVFoundation, the alternative of QTKit, does not have the volume control for MIDI. I have to admit this does not meet the requirement of simutrans.

So, I tried to use SDL_mixier to play sound and music. It worked fine on wav, but SDL_mixier cannot load MIDI on Mac. Unfortunately SDL_mixier outputs no error message despite its loading failure.
I also tried to realize the volume control on AVMIDIPlayer but nothing useful was found.

Though pre-compiled simutrans with QTKit works fine even with the latest macOS, I worry about the possibility that Apple suddenly makes QTKit not executable. The fact that current simutrans code needs some tricky modification to compile it on Mac is a huge obstacle for new developers with Mac, and this is a loss for simutrans development community. This patch should be included as soon as possible despite its loss of volume control.

An_dz

Just two questions:

1. At least you can mute it?

2. Does this patch allow Xcode to compile Simutrans out-of-the-box?

TurfIt

Does not compile with 10.9.5.


void dr_set_midi_volume(int const vol)
                                  ^
music/core-audio_midi.mm:29:2: error: unknown type name 'AVMIDIPlayer'; did you mean 'AVPlayer'?
        AVMIDIPlayer*  const player = [[AVMIDIPlayer alloc] initWithContentsOfURL:url soundBankURL: nil error: nil];
        ^~~~~~~~~~~~
        AVPlayer
/System/Library/Frameworks/AVFoundation.framework/Headers/AVPlayerLayer.h:42:8: note: 'AVPlayer' declared here
@class AVPlayer;
       ^
music/core-audio_midi.mm:29:34: error: use of undeclared identifier 'AVMIDIPlayer'; did you mean 'AVPlayer'?
        AVMIDIPlayer*  const player = [[AVMIDIPlayer alloc] initWithContentsOfURL:url soundBankURL: nil error: nil];
                                        ^
/System/Library/Frameworks/AVFoundation.framework/Headers/AVPlayerLayer.h:42:8: note: 'AVPlayer' declared here
@class AVPlayer;
       ^
music/core-audio_midi.mm:31:11: warning: 'AVPlayer' may not respond to 'prepareToPlay'
                [player prepareToPlay];
                 ~~~~~~ ^
music/core-audio_midi.mm:41:2: error: unknown type name 'AVMIDIPlayer'; did you mean 'AVPlayer'?
        AVMIDIPlayer* const player = [players objectAtIndex: key];
        ^~~~~~~~~~~~
        AVPlayer
/System/Library/Frameworks/AVFoundation.framework/Headers/AVPlayerLayer.h:42:8: note: 'AVPlayer' declared here
@class AVPlayer;
       ^
music/core-audio_midi.mm:42:10: warning: instance method '-play:' not found (return type defaults to 'id')
      [-Wobjc-method-access]
        [player play: ^{}];
                ^~~~
/System/Library/Frameworks/AVFoundation.framework/Headers/AVPlayer.h:63:12: note: receiver is instance of class declared
      here
@interface AVPlayer : NSObject
           ^
music/core-audio_midi.mm:50:2: error: unknown type name 'AVMIDIPlayer'; did you mean 'AVPlayer'?
        AVMIDIPlayer* const player = [players objectAtIndex: nowPlaying];
        ^~~~~~~~~~~~
        AVPlayer
/System/Library/Frameworks/AVFoundation.framework/Headers/AVPlayerLayer.h:42:8: note: 'AVPlayer' declared here
@class AVPlayer;
       ^
music/core-audio_midi.mm:51:10: warning: 'AVPlayer' may not respond to 'stop'
        [player stop];
         ~~~~~~ ^
4 warnings and 4 errors generated.

THLeaderH

Quote1. At least you can mute it?
Yes it can.
Quote2. Does this patch allow Xcode to compile Simutrans out-of-the-box?
I haven't used Xcode for simutrans coding so I'm not sure.
QuoteDoes not compile with 10.9.5.
Yes, it's true, since AVMIDIPlayer is supported on macOS 10.10+ (see here).
So we have to give an option whether using QTKit or AVFoundation in config.default.

THLeaderH

I made a little fix on this patch.
Code with AVFoundation cannot be compiled with old macOS, so I added "AV_FOUNDATION = 1" option in config.default.
If the version of macOS is 10.12 or later,
AV_FOUNDATION = 1
must be added in config.default and the code becomes compilable. Without this parameter, the code with QTKit will be used.
Leaving compiling difficult on the latest macOS is far more severe than other issues like losing the volume control, I insist.

prissi

SInce I lack a Mac, I trust you say here ... in in r8236
Thank you

mstea

Thanks very much for incorporating the patch! I think you may have missed part of the submitted patch, however - the AVF* files are missing, even though the code that adds them to the sources in the Makefile was included.

prissi

Oh, right, added them too. Thanks for noticing.

THLeaderH

I tested r8239 and it works fine :)
Thank you very much.

Ters

Does this mean there should be two builds, one for older Macs using the old code and one for newer Macs using the new code?

THLeaderH

It doesn't have to but it should. The current latest macOS (10.12) allows executing binary with QTKit, but cannot compile the code with QTKit. Since simutrans with AVFoundation loses volume control, I think the executable binary with AVFoundation doesn't have to be distributed as an official release.