~ppsspp/ppsspp/ppsspp_1.3.0

« back to all changes in this revision

Viewing changes to ios/AudioEngine.mm

  • Committer: Sérgio Benjamim
  • Date: 2017-01-02 00:12:05 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20170102001205-cxbta9za203nmjwm
1.3.0 source (from ppsspp_1.3.0-r160.p5.l1762.a165.t83~56~ubuntu16.04.1.tar.xz).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
//  AudioEngine.mm
 
3
//  PPSSPP
 
4
//
 
5
//  Created by rock88 on 15/03/2013.
 
6
//  Copyright (c) 2013 Homebrew. All rights reserved.
 
7
//
 
8
 
 
9
#import "AudioEngine.h"
 
10
#import <OpenAL/al.h>
 
11
#import <OpenAL/alc.h>
 
12
#import <AudioToolbox/AudioToolbox.h>
 
13
#import <AVFoundation/AVFoundation.h>
 
14
 
 
15
#import <string>
 
16
 
 
17
static volatile BOOL done = 0;
 
18
 
 
19
#define SAMPLE_SIZE 44100
 
20
static short stream[SAMPLE_SIZE];
 
21
 
 
22
int NativeMix(short *audio, int num_samples);
 
23
 
 
24
@interface AudioEngine ()
 
25
 
 
26
@property (nonatomic,assign) ALCdevice *alcDevice;
 
27
@property (nonatomic,assign) ALCcontext *alContext;
 
28
@property (nonatomic,assign) ALuint buffer;
 
29
@property (nonatomic,assign) ALuint source;
 
30
 
 
31
@end
 
32
 
 
33
@implementation AudioEngine
 
34
@synthesize alcDevice,alContext,buffer,source;
 
35
 
 
36
- (id)init
 
37
{
 
38
    self = [super init];
 
39
    if (self)
 
40
    {
 
41
        [self audioInit];
 
42
        [self audioLoop];
 
43
    }
 
44
    return self;
 
45
}
 
46
 
 
47
- (void)dealloc
 
48
{
 
49
    [self audioShutdown];
 
50
    [super dealloc];
 
51
}
 
52
 
 
53
- (void)checkALError
 
54
{
 
55
    ALenum ErrCode;
 
56
    std::string Err = "OpenAL error: ";
 
57
    if ((ErrCode = alGetError()) != AL_NO_ERROR)
 
58
    {
 
59
        Err += (char *)alGetString(ErrCode);
 
60
        printf("%s\n",Err.c_str());
 
61
    }
 
62
}
 
63
 
 
64
- (void)audioInit
 
65
{
 
66
    done = 0;
 
67
    alcDevice = alcOpenDevice(NULL);
 
68
    
 
69
    if (alcDevice)
 
70
    {
 
71
        NSLog(@"OpenAL device opened: %s",alcGetString(alcDevice, ALC_DEVICE_SPECIFIER));
 
72
    }
 
73
    else
 
74
    {
 
75
        NSLog(@"WARNING: could not open OpenAL device");
 
76
        return;
 
77
    }
 
78
    
 
79
    alContext = alcCreateContext(alcDevice, NULL);
 
80
    
 
81
    if (alContext)
 
82
    {
 
83
        alcMakeContextCurrent(alContext);
 
84
    }
 
85
    else
 
86
    {
 
87
        NSLog(@"ERROR: no OpenAL context");
 
88
        return;
 
89
    }
 
90
    
 
91
    alGenSources(1, &source);
 
92
    alGenBuffers(1, &buffer);
 
93
}
 
94
 
 
95
- (void)audioShutdown
 
96
{
 
97
    done = 1;
 
98
    alcMakeContextCurrent(NULL);
 
99
    
 
100
    if (alContext)
 
101
    {
 
102
        alcDestroyContext(alContext);
 
103
        alContext = NULL;
 
104
    }
 
105
    
 
106
    if (alcDevice)
 
107
    {
 
108
        alcCloseDevice(alcDevice);
 
109
        alcDevice = NULL;
 
110
    }
 
111
}
 
112
 
 
113
- (bool)playing
 
114
{
 
115
    ALenum state;
 
116
    alGetSourcei(source, AL_SOURCE_STATE, &state);
 
117
    return (state == AL_PLAYING);
 
118
}
 
119
 
 
120
- (void)audioLoop
 
121
{
 
122
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
 
123
        while (!done)
 
124
        {
 
125
            size_t frames_ready;
 
126
            if (![self playing])
 
127
                frames_ready = NativeMix(stream, SAMPLE_SIZE / 2);
 
128
            else
 
129
                frames_ready = 0;
 
130
 
 
131
            if (frames_ready > 0)
 
132
            {
 
133
                const size_t bytes_ready = frames_ready * sizeof(short) * 2;
 
134
                alSourcei(source, AL_BUFFER, 0);
 
135
                alBufferData(buffer, AL_FORMAT_STEREO16, stream, bytes_ready, 44100);
 
136
                alSourcei(source, AL_BUFFER, buffer);
 
137
                alSourcePlay(source);
 
138
 
 
139
                // TODO: Maybe this could get behind?
 
140
                usleep((1000000 * frames_ready) / 44100);
 
141
            }
 
142
            else
 
143
                usleep(100);
 
144
            pthread_yield_np();
 
145
        }
 
146
    });
 
147
}
 
148
 
 
149
@end