Subversion Repositories Kolibri OS

Rev

Rev 1696 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1696 Rev 2349
1
#include 
1
#include 
2
#include 
2
#include 
3
#include 
3
#include 
4
#include 
4
#include 
5
 
5
 
6
#include 
6
#include 
7
#include 
7
#include 
8
#include "sound.h"
8
#include "sound.h"
9
#include "fplay.h"
9
#include "fplay.h"
10
 
10
 
11
 
11
 
12
astream_t astream;
12
astream_t astream;
13
 
13
 
14
static SNDBUF hBuff;
14
static SNDBUF hBuff;
15
 
15
 
16
extern volatile uint32_t status;
16
extern uint8_t *decoder_buffer;
17
 
17
 
18
void audio_thread(void *param);
18
extern volatile uint32_t status;
19
 
-
 
20
void spinlock_lock(volatile uint32_t *val)
-
 
21
{
-
 
22
    uint32_t tmp;
-
 
23
 
-
 
24
    __asm__ __volatile__ (
-
 
25
"0:\n\t"
-
 
26
    "mov %0, %1\n\t"
-
 
27
    "testl %1, %1\n\t"
-
 
28
    "jz 1f\n\t"
-
 
29
 
-
 
30
    "movl $68, %%eax\n\t"
-
 
31
    "movl $1,  %%ebx\n\t"
-
 
32
    "int  $0x40\n\t"
-
 
33
    "jmp 0b\n\t"
-
 
34
"1:\n\t"
-
 
35
    "incl %1\n\t"
-
 
36
    "xchgl %0, %1\n\t"
-
 
37
    "testl %1, %1\n\t"
-
 
38
	"jnz 0b\n"
-
 
39
    : "+m" (*val), "=&r"(tmp)
19
 
40
    ::"eax","ebx" );
20
extern volatile uint32_t driver_lock;
41
}
21
 
42
 
22
 
43
static int snd_format;
23
static int snd_format;
44
int sample_rate;
24
int sample_rate;
45
 
25
 
46
int init_audio(int format)
26
int init_audio(int format)
47
{
27
{
48
    int    err;
28
    int    err;
49
    int    version =-1;
29
    int    version =-1;
50
    char  *errstr;
30
    char  *errstr;
51
 
31
 
-
 
32
    mutex_lock(&driver_lock);
-
 
33
 
52
    if((err = InitSound(&version)) !=0 )
34
    if((err = InitSound(&version)) !=0 )
53
    {
35
    {
-
 
36
        mutex_unlock(&driver_lock);
54
        errstr = "Sound service not installed\n\r";
37
        errstr = "Sound service not installed\n\r";
55
        goto exit_whith_error;
38
        goto exit_whith_error;
56
    }
39
    };
-
 
40
 
-
 
41
    mutex_unlock(&driver_lock);
-
 
42
 
57
    printf("sound version 0x%x\n", version);
43
    printf("sound version 0x%x\n", version);
58
 
44
 
59
    if( (SOUND_VERSION>(version&0xFFFF)) ||
45
    if( (SOUND_VERSION>(version&0xFFFF)) ||
60
        (SOUND_VERSION<(version >> 16)))
46
        (SOUND_VERSION<(version >> 16)))
61
    {
47
    {
62
        errstr = "Sound service version mismatch\n\r";
48
        errstr = "Sound service version mismatch\n\r";
63
        goto exit_whith_error;
49
        goto exit_whith_error;
64
    }
50
    }
65
 
51
 
66
    snd_format = format;
52
    snd_format = format;
67
 
53
 
68
    asm volatile ( "xchgw %bx, %bx");
-
 
69
 
-
 
70
    create_thread(audio_thread, 0, 163840);
54
    create_thread(audio_thread, 0, 163840);
71
 
55
 
72
    return 1;
56
    return 1;
73
 
57
 
74
exit_whith_error:
58
exit_whith_error:
75
 
59
 
76
    printf(errstr);
60
    printf(errstr);
77
    return 0;
61
    return 0;
78
};
62
};
79
 
63
 
80
static uint64_t samples_lost;
64
static uint64_t samples_lost;
81
static double  audio_delta;
65
static double  audio_delta;
82
 
66
 
83
double get_master_clock()
67
double get_master_clock()
84
{
68
{
85
    double tstamp;
69
    double tstamp;
86
 
70
 
87
    GetTimeStamp(hBuff, &tstamp);
71
    GetTimeStamp(hBuff, &tstamp);
88
    return tstamp - audio_delta;
72
    return tstamp - audio_delta;
89
};
73
};
90
 
74
 
-
 
75
int decode_audio(AVCodecContext  *ctx, queue_t *qa)
-
 
76
{
-
 
77
    AVPacket   pkt;
-
 
78
    AVPacket    pkt_tmp;
-
 
79
 
-
 
80
    uint8_t    *audio_data;
-
 
81
    int         audio_size;
-
 
82
    int         len;
-
 
83
    int         data_size=0;
-
 
84
 
-
 
85
    if( astream.count > AVCODEC_MAX_AUDIO_FRAME_SIZE*7)
-
 
86
        return 1;
-
 
87
 
-
 
88
    if( get_packet(qa, &pkt) == 0 )
-
 
89
        return 0;
-
 
90
 
-
 
91
 //          __asm__("int3");
-
 
92
 
-
 
93
    pkt_tmp = pkt;
-
 
94
 
-
 
95
    while(pkt_tmp.size > 0)
-
 
96
    {
-
 
97
        data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
-
 
98
 
-
 
99
        len = avcodec_decode_audio3(ctx,(int16_t*)decoder_buffer,
-
 
100
                                   &data_size, &pkt_tmp);
-
 
101
 
-
 
102
        if(len >= 0)
-
 
103
        {
-
 
104
            pkt_tmp.data += len;
-
 
105
            pkt_tmp.size -= len;
-
 
106
 
-
 
107
            mutex_lock(&astream.lock);
-
 
108
            memcpy(astream.buffer+astream.count, decoder_buffer, data_size);
-
 
109
            astream.count += data_size;
-
 
110
            mutex_unlock(&astream.lock);
-
 
111
       }
-
 
112
       else pkt_tmp.size = 0;
-
 
113
    }
-
 
114
    av_free_packet(&pkt);
-
 
115
    return 1;
-
 
116
};
-
 
117
 
91
 
118
 
92
void audio_thread(void *param)
119
int audio_thread(void *param)
93
{
120
{
94
    SND_EVENT evnt;
121
    SND_EVENT evnt;
95
    int       buffsize;
122
    int       buffsize;
96
    int      samples;
123
    int      samples;
97
    int       err;
124
    int       err;
98
    char     *errstr;
125
    char     *errstr;
99
 
126
 
100
 
127
 
101
    if((err = CreateBuffer(snd_format|PCM_RING,0, &hBuff)) != 0)
128
    if((err = CreateBuffer(snd_format|PCM_RING,0, &hBuff)) != 0)
102
    {
129
    {
103
        errstr = "Cannot create sound buffer\n\r";
130
        errstr = "Cannot create sound buffer\n\r";
104
        goto exit_whith_error;
131
        goto exit_whith_error;
105
    };
132
    };
106
 
133
 
107
    SetVolume(hBuff,-1000,-1000);
134
    SetVolume(hBuff,-1000,-1000);
108
 
135
 
109
    if((err = GetBufferSize(hBuff, &buffsize)) != 0)
136
    if((err = GetBufferSize(hBuff, &buffsize)) != 0)
110
    {
137
    {
111
        errstr = "Cannot get buffer size\n\r";
138
        errstr = "Cannot get buffer size\n\r";
112
        goto exit_whith_error;
139
        goto exit_whith_error;
113
    };
140
    };
114
 
141
 
115
    buffsize = buffsize/2;
142
    buffsize = buffsize/2;
116
 
143
 
117
    samples = buffsize/4;
144
    samples = buffsize/4;
118
 
145
 
119
    while( (astream.count < buffsize*2) &&
146
    while( (astream.count < buffsize*2) &&
120
               (status != 0) )
147
               (status != 0) )
121
        yield();
148
        yield();
122
 
149
 
123
    spinlock_lock(&astream.lock);
150
    mutex_lock(&astream.lock);
124
    {
151
    {
125
        SetBuffer(hBuff, astream.buffer, 0, buffsize);
152
        SetBuffer(hBuff, astream.buffer, 0, buffsize);
126
        astream.count -= buffsize;
153
        astream.count -= buffsize;
127
        if(astream.count)
154
        if(astream.count)
128
            memcpy(astream.buffer, astream.buffer+buffsize, astream.count);
155
            memcpy(astream.buffer, astream.buffer+buffsize, astream.count);
129
        spinlock_unlock(&astream.lock);
156
        mutex_unlock(&astream.lock);
130
    };
157
    };
131
 
158
 
132
    if((err = PlayBuffer(hBuff, 0)) !=0 )
159
    if((err = PlayBuffer(hBuff, 0)) !=0 )
133
    {
160
    {
134
        errstr = "Cannot play buffer\n\r";
161
        errstr = "Cannot play buffer\n\r";
135
        goto exit_whith_error;
162
        goto exit_whith_error;
136
    };
163
    };
137
 
164
 
138
 
165
 
139
#ifdef BLACK_MAGIC_SOUND
166
#ifdef BLACK_MAGIC_SOUND
140
 
167
 
141
    while( status != 0)
168
    while( status != 0)
142
    {
169
    {
143
        uint32_t  offset;
170
        uint32_t  offset;
144
 
171
 
145
        GetNotify(&evnt);
172
        GetNotify(&evnt);
146
 
173
 
147
        if(evnt.code != 0xFF000001)
174
        if(evnt.code != 0xFF000001)
148
        {
175
        {
149
            printf("invalid event code %d\n\r", evnt.code);
176
            printf("invalid event code %d\n\r", evnt.code);
150
            continue;
177
            continue;
151
        }
178
        }
152
 
179
 
153
        if(evnt.stream != hBuff)
180
        if(evnt.stream != hBuff)
154
        {
181
        {
155
            printf("invalid stream %x hBuff= %x\n\r",
182
            printf("invalid stream %x hBuff= %x\n\r",
156
                    evnt.stream, hBuff);
183
                    evnt.stream, hBuff);
157
            continue;
184
            continue;
158
        }
185
        }
159
 
186
 
160
        GetTimeStamp(hBuff, &audio_delta);
187
        GetTimeStamp(hBuff, &audio_delta);
161
        samples_lost = audio_delta*sample_rate/1000;
188
        samples_lost = audio_delta*sample_rate/1000;
162
 
189
 
163
        offset = evnt.offset;
190
        offset = evnt.offset;
164
 
191
 
165
        spinlock_lock(&astream.lock);
192
        mutex_lock(&astream.lock);
166
        {
193
        {
167
            SetBuffer(hBuff, astream.buffer, offset, buffsize);
194
            SetBuffer(hBuff, astream.buffer, offset, buffsize);
168
            astream.count -= buffsize;
195
            astream.count -= buffsize;
169
            if(astream.count)
196
            if(astream.count)
170
                memcpy(astream.buffer, astream.buffer+buffsize, astream.count);
197
                memcpy(astream.buffer, astream.buffer+buffsize, astream.count);
171
            spinlock_unlock(&astream.lock);
198
            mutex_unlock(&astream.lock);
172
        };
199
        };
173
        break;
200
        break;
174
    };
201
    };
175
#endif
202
#endif
176
 
203
 
177
    printf("initial audio delta %f\n", audio_delta);
204
    printf("initial audio delta %f\n", audio_delta);
178
 
205
 
179
    while( status != 0)
206
    while( status != 0)
180
    {
207
    {
181
        uint32_t  offset;
208
        uint32_t  offset;
182
        double    event_stamp, wait_stamp;
209
        double    event_stamp, wait_stamp;
183
        int       too_late = 0;
210
        int       too_late = 0;
184
 
211
 
185
        GetNotify(&evnt);
212
        GetNotify(&evnt);
186
 
213
 
187
        if(evnt.code != 0xFF000001)
214
        if(evnt.code != 0xFF000001)
188
        {
215
        {
189
            printf("invalid event code %d\n\r", evnt.code);
216
            printf("invalid event code %d\n\r", evnt.code);
190
            continue;
217
            continue;
191
        }
218
        }
192
 
219
 
193
        if(evnt.stream != hBuff)
220
        if(evnt.stream != hBuff)
194
        {
221
        {
195
            printf("invalid stream %x hBuff= %x\n\r",
222
            printf("invalid stream %x hBuff= %x\n\r",
196
                    evnt.stream, hBuff);
223
                    evnt.stream, hBuff);
197
            continue;
224
            continue;
198
        };
225
        };
199
 
226
 
200
        GetTimeStamp(hBuff, &event_stamp);
227
        GetTimeStamp(hBuff, &event_stamp);
201
 
228
 
202
        offset = evnt.offset;
229
        offset = evnt.offset;
203
 
230
 
204
        while( (astream.count < buffsize) &&
231
        while( (astream.count < buffsize) &&
205
               (status != 0) )
232
               (status != 0) )
206
        {
233
        {
207
            yield();
234
            yield();
208
            GetTimeStamp(hBuff, &wait_stamp);
235
            GetTimeStamp(hBuff, &wait_stamp);
209
            if( (wait_stamp - event_stamp) >
236
            if( (wait_stamp - event_stamp) >
210
                 samples*1500/sample_rate )
237
                 samples*1500/sample_rate )
211
            {
238
            {
212
                samples_lost+= samples;
239
                samples_lost+= samples;
213
                audio_delta = (double)samples_lost*1000/sample_rate;
240
                audio_delta = (double)samples_lost*1000/sample_rate;
214
//                printf("audio delta %f\n", audio_delta);
241
//                printf("audio delta %f\n", audio_delta);
215
                too_late = 1;
242
                too_late = 1;
216
                break;
243
                break;
217
            }
244
            }
218
        };
245
        };
219
 
246
 
220
        if((too_late == 1) || (status == 0))
247
        if((too_late == 1) || (status == 0))
221
            continue;
248
            continue;
222
 
249
 
223
        spinlock_lock(&astream.lock);
250
        mutex_lock(&astream.lock);
224
        SetBuffer(hBuff, astream.buffer, offset, buffsize);
251
        SetBuffer(hBuff, astream.buffer, offset, buffsize);
225
        astream.count -= buffsize;
252
        astream.count -= buffsize;
226
        if(astream.count)
253
        if(astream.count)
227
            memcpy(astream.buffer, astream.buffer+buffsize, astream.count);
254
            memcpy(astream.buffer, astream.buffer+buffsize, astream.count);
228
        spinlock_unlock(&astream.lock);
255
        mutex_unlock(&astream.lock);
229
    }
256
    }
230
 
257
 
-
 
258
    StopBuffer(hBuff);
-
 
259
    DestroyBuffer(hBuff);
-
 
260
 
231
    return;
261
    return 0;
232
 
262
 
233
exit_whith_error:
263
exit_whith_error:
234
 
264
 
235
    printf(errstr);
265
    printf(errstr);
236
    return ;
266
    return -1;
237
 
267
 
238
};
268
};