~ubuntu-branches/debian/sid/mame/sid

« back to all changes in this revision

Viewing changes to mess/src/emu/sound/cdda.c

  • Committer: Package Import Robot
  • Author(s): Jordi Mallach, Jordi Mallach, Emmanuel Kasper
  • Date: 2011-12-19 22:56:27 UTC
  • mfrom: (0.1.2)
  • Revision ID: package-import@ubuntu.com-20111219225627-ub5oga1oys4ogqzm
Tags: 0.144-1
[ Jordi Mallach ]
* Fix syntax errors in DEP5 copyright file (lintian).
* Use a versioned copyright Format specification field.
* Update Vcs-* URLs.
* Move transitional packages to the new metapackages section, and make
  them priority extra.
* Remove references to GNU/Linux and MESS sources from copyright.
* Add build variables for s390x.
* Use .xz tarballs as it cuts 4MB for the upstream sources.
* Add nplayers.ini as a patch. Update copyright file to add CC-BY-SA-3.0.

[ Emmanuel Kasper ]
* New upstream release. Closes: #651538.
* Add Free Desktop compliant png icons of various sizes taken from
  the hydroxygen iconset
* Mess is now built from a new source package, to avoid possible source
  incompatibilities between mame and the mess overlay.
* Mame-tools are not built from the mame source package anymore, but
  from the mess source package

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
    CD-DA "Red Book" audio sound hardware handler
3
 
    Relies on the actual CD logic and reading in cdrom.c.
4
 
*/
5
 
 
6
 
#include "emu.h"
7
 
#include "cdrom.h"
8
 
#include "cdda.h"
9
 
 
10
 
typedef struct _cdda_info cdda_info;
11
 
struct _cdda_info
12
 
{
13
 
        sound_stream *          stream;
14
 
        cdrom_file *            disc;
15
 
 
16
 
        INT8                            audio_playing, audio_pause, audio_ended_normally;
17
 
        UINT32                          audio_lba, audio_length;
18
 
 
19
 
        UINT8 *                         audio_cache;
20
 
        UINT32                          audio_samples;
21
 
        UINT32                          audio_bptr;
22
 
};
23
 
 
24
 
INLINE cdda_info *get_safe_token(device_t *device)
25
 
{
26
 
        assert(device != NULL);
27
 
        assert(device->type() == CDDA);
28
 
        return (cdda_info *)downcast<legacy_device_base *>(device)->token();
29
 
}
30
 
 
31
 
#define MAX_SECTORS ( 4 )
32
 
 
33
 
static void get_audio_data(cdda_info *info, stream_sample_t *bufL, stream_sample_t *bufR, UINT32 samples_wanted);
34
 
 
35
 
 
36
 
/*-------------------------------------------------
37
 
    cdda_update - stream update callback
38
 
-------------------------------------------------*/
39
 
 
40
 
static STREAM_UPDATE( cdda_update )
41
 
{
42
 
        cdda_info *info = (cdda_info *)param;
43
 
        get_audio_data(info, &outputs[0][0], &outputs[1][0], samples);
44
 
}
45
 
 
46
 
 
47
 
/*-------------------------------------------------
48
 
    DEVICE_START( cdda ) - audio start callback
49
 
-------------------------------------------------*/
50
 
 
51
 
static DEVICE_START( cdda )
52
 
{
53
 
        //const struct CDDAinterface *intf;
54
 
        cdda_info *info = get_safe_token(device);
55
 
 
56
 
        /* allocate an audio cache */
57
 
        info->audio_cache = auto_alloc_array( device->machine(), UINT8, CD_MAX_SECTOR_DATA * MAX_SECTORS );
58
 
 
59
 
        //intf = (const struct CDDAinterface *)device->static_config();
60
 
 
61
 
        info->stream = device->machine().sound().stream_alloc(*device, 0, 2, 44100, info, cdda_update);
62
 
 
63
 
        device->save_item( NAME(info->audio_playing) );
64
 
        device->save_item( NAME(info->audio_pause) );
65
 
        device->save_item( NAME(info->audio_ended_normally) );
66
 
        device->save_item( NAME(info->audio_lba) );
67
 
        device->save_item( NAME(info->audio_length) );
68
 
        device->save_pointer( NAME(info->audio_cache), CD_MAX_SECTOR_DATA * MAX_SECTORS );
69
 
        device->save_item( NAME(info->audio_samples) );
70
 
        device->save_item( NAME(info->audio_bptr) );
71
 
}
72
 
 
73
 
 
74
 
/*-------------------------------------------------
75
 
    cdda_set_cdrom - set the CD-ROM file for the
76
 
    given CDDA stream
77
 
-------------------------------------------------*/
78
 
 
79
 
void cdda_set_cdrom(device_t *device, void *file)
80
 
{
81
 
        cdda_info *info = get_safe_token(device);
82
 
        info->disc = (cdrom_file *)file;
83
 
}
84
 
 
85
 
 
86
 
/*-------------------------------------------------
87
 
    cdda_from_cdrom - find the CDDA stream
88
 
    that references the given CD-ROM file
89
 
-------------------------------------------------*/
90
 
 
91
 
device_t *cdda_from_cdrom(running_machine &machine, void *file)
92
 
{
93
 
        device_sound_interface *sound = NULL;
94
 
 
95
 
        for (bool gotone = machine.devicelist().first(sound); gotone; gotone = sound->next(sound))
96
 
                if (sound->device().type() == CDDA)
97
 
                {
98
 
                        cdda_info *info = get_safe_token(*sound);
99
 
                        if (info->disc == file)
100
 
                                return *sound;
101
 
                }
102
 
 
103
 
        return NULL;
104
 
}
105
 
 
106
 
 
107
 
/*-------------------------------------------------
108
 
    cdda_start_audio - begin playback of a Red
109
 
    Book audio track
110
 
-------------------------------------------------*/
111
 
 
112
 
void cdda_start_audio(device_t *device, UINT32 startlba, UINT32 numblocks)
113
 
{
114
 
        cdda_info *info = get_safe_token(device);
115
 
 
116
 
        info->stream->update();
117
 
        info->audio_playing = TRUE;
118
 
        info->audio_pause = FALSE;
119
 
        info->audio_ended_normally = FALSE;
120
 
        info->audio_lba = startlba;
121
 
        info->audio_length = numblocks;
122
 
}
123
 
 
124
 
 
125
 
/*-------------------------------------------------
126
 
    cdda_stop_audio - stop playback of a Red Book
127
 
    audio track
128
 
-------------------------------------------------*/
129
 
 
130
 
void cdda_stop_audio(device_t *device)
131
 
{
132
 
        cdda_info *info = get_safe_token(device);
133
 
 
134
 
        info->stream->update();
135
 
        info->audio_playing = FALSE;
136
 
        info->audio_ended_normally = TRUE;
137
 
}
138
 
 
139
 
 
140
 
/*-------------------------------------------------
141
 
    cdda_pause_audio - pause/unpause playback of
142
 
    a Red Book audio track
143
 
-------------------------------------------------*/
144
 
 
145
 
void cdda_pause_audio(device_t *device, int pause)
146
 
{
147
 
        cdda_info *info = get_safe_token(device);
148
 
 
149
 
        info->stream->update();
150
 
        info->audio_pause = pause;
151
 
}
152
 
 
153
 
 
154
 
/*-------------------------------------------------
155
 
    cdda_get_audio_lba - returns the current LBA
156
 
    (physical sector) during Red Book playback
157
 
-------------------------------------------------*/
158
 
 
159
 
UINT32 cdda_get_audio_lba(device_t *device)
160
 
{
161
 
        cdda_info *info = get_safe_token(device);
162
 
 
163
 
        info->stream->update();
164
 
        return info->audio_lba;
165
 
}
166
 
 
167
 
 
168
 
/*-------------------------------------------------
169
 
    cdda_audio_active - returns Red Book audio
170
 
    playback status
171
 
-------------------------------------------------*/
172
 
 
173
 
int cdda_audio_active(device_t *device)
174
 
{
175
 
        cdda_info *info = get_safe_token(device);
176
 
 
177
 
        info->stream->update();
178
 
        return info->audio_playing;
179
 
}
180
 
 
181
 
 
182
 
/*-------------------------------------------------
183
 
    cdda_audio_paused - returns if Red Book
184
 
    playback is paused
185
 
-------------------------------------------------*/
186
 
 
187
 
int cdda_audio_paused(device_t *device)
188
 
{
189
 
        cdda_info *info = get_safe_token(device);
190
 
        return info->audio_pause;
191
 
}
192
 
 
193
 
 
194
 
/*-------------------------------------------------
195
 
    cdda_audio_ended - returns if a Red Book
196
 
    track reached it's natural end
197
 
-------------------------------------------------*/
198
 
 
199
 
int cdda_audio_ended(device_t *device)
200
 
{
201
 
        cdda_info *info = get_safe_token(device);
202
 
        return info->audio_ended_normally;
203
 
}
204
 
 
205
 
 
206
 
/*-------------------------------------------------
207
 
    get_audio_data - reads Red Book data off
208
 
    the disc if playback is in progress and
209
 
    converts it to 2 16-bit 44.1 kHz streams
210
 
-------------------------------------------------*/
211
 
 
212
 
static void get_audio_data(cdda_info *info, stream_sample_t *bufL, stream_sample_t *bufR, UINT32 samples_wanted)
213
 
{
214
 
        int i, sectoread, remaining;
215
 
        INT16 *audio_cache = (INT16 *) info->audio_cache;
216
 
 
217
 
        /* if no file, audio not playing, audio paused, or out of disc data,
218
 
       just zero fill */
219
 
        if (!info->disc || !info->audio_playing || info->audio_pause || (!info->audio_length && !info->audio_samples))
220
 
        {
221
 
                if( info->disc && info->audio_playing && !info->audio_pause && !info->audio_length )
222
 
                {
223
 
                        info->audio_playing = FALSE;
224
 
                        info->audio_ended_normally = TRUE;
225
 
                }
226
 
 
227
 
                memset(bufL, 0, sizeof(stream_sample_t)*samples_wanted);
228
 
                memset(bufR, 0, sizeof(stream_sample_t)*samples_wanted);
229
 
                return;
230
 
        }
231
 
 
232
 
        /* if we've got enough samples, just feed 'em out */
233
 
        if (samples_wanted <= info->audio_samples)
234
 
        {
235
 
                for (i = 0; i < samples_wanted; i++)
236
 
                {
237
 
                        *bufL++ = audio_cache[ info->audio_bptr++ ];
238
 
                        *bufR++ = audio_cache[ info->audio_bptr++ ];
239
 
                }
240
 
 
241
 
                info->audio_samples -= samples_wanted;
242
 
                return;
243
 
        }
244
 
 
245
 
        /* we don't have enough, so first feed what we've got */
246
 
        for (i = 0; i < info->audio_samples; i++)
247
 
        {
248
 
                *bufL++ = audio_cache[ info->audio_bptr++ ];
249
 
                *bufR++ = audio_cache[ info->audio_bptr++ ];
250
 
        }
251
 
 
252
 
        /* remember how much left for later */
253
 
        remaining = samples_wanted - info->audio_samples;
254
 
 
255
 
        /* reset the buffer and get what we can from the disc */
256
 
        info->audio_samples = 0;
257
 
        if (info->audio_length >= MAX_SECTORS)
258
 
        {
259
 
                sectoread = MAX_SECTORS;
260
 
        }
261
 
        else
262
 
        {
263
 
                sectoread = info->audio_length;
264
 
        }
265
 
 
266
 
        for (i = 0; i < sectoread; i++)
267
 
        {
268
 
                cdrom_read_data(info->disc, info->audio_lba, &info->audio_cache[CD_MAX_SECTOR_DATA*i], CD_TRACK_AUDIO);
269
 
 
270
 
                info->audio_lba++;
271
 
        }
272
 
 
273
 
        info->audio_samples = (CD_MAX_SECTOR_DATA*sectoread)/4;
274
 
        info->audio_length -= sectoread;
275
 
 
276
 
        /* CD-DA data on the disc is big-endian, flip if we're not */
277
 
        if (ENDIANNESS_NATIVE == ENDIANNESS_LITTLE)
278
 
        {
279
 
                for( i = 0; i < info->audio_samples * 2; i++ )
280
 
                {
281
 
                        audio_cache[ i ] = BIG_ENDIANIZE_INT16( audio_cache[ i ] );
282
 
                }
283
 
        }
284
 
 
285
 
        /* reset feedout ptr */
286
 
        info->audio_bptr = 0;
287
 
 
288
 
        /* we've got data, feed it out by calling ourselves recursively */
289
 
        get_audio_data(info, bufL, bufR, remaining);
290
 
}
291
 
 
292
 
/*-------------------------------------------------
293
 
    cdda_set_volume - sets CD-DA volume level
294
 
    for both speakers, used for fade in/out effects
295
 
-------------------------------------------------*/
296
 
 
297
 
void cdda_set_volume(device_t *device,int volume)
298
 
{
299
 
        cdda_info *cdda = get_safe_token(device);
300
 
 
301
 
        cdda->stream->set_output_gain(0,volume / 100.0);
302
 
        cdda->stream->set_output_gain(1,volume / 100.0);
303
 
}
304
 
 
305
 
/*-------------------------------------------------
306
 
    cdda_set_channel_volume - sets CD-DA volume level
307
 
    for either speaker, used for fade in/out effects
308
 
-------------------------------------------------*/
309
 
 
310
 
void cdda_set_channel_volume(device_t *device, int channel, int volume)
311
 
{
312
 
        cdda_info *cdda = get_safe_token(device);
313
 
 
314
 
        if(channel == 0)
315
 
                cdda->stream->set_output_gain(0,volume / 100.0);
316
 
        if(channel == 1)
317
 
                cdda->stream->set_output_gain(1,volume / 100.0);
318
 
}
319
 
 
320
 
/**************************************************************************
321
 
 * Generic get_info
322
 
 **************************************************************************/
323
 
 
324
 
DEVICE_GET_INFO( cdda )
325
 
{
326
 
        switch (state)
327
 
        {
328
 
                /* --- the following bits of info are returned as 64-bit signed integers --- */
329
 
                case DEVINFO_INT_TOKEN_BYTES:                                   info->i = sizeof(cdda_info);                            break;
330
 
 
331
 
                /* --- the following bits of info are returned as pointers to data or functions --- */
332
 
                case DEVINFO_FCT_START:                                                 info->start = DEVICE_START_NAME( cdda );                break;
333
 
                case DEVINFO_FCT_STOP:                                                  /* nothing */                                                           break;
334
 
                case DEVINFO_FCT_RESET:                                                 /* nothing */                                                           break;
335
 
 
336
 
                /* --- the following bits of info are returned as NULL-terminated strings --- */
337
 
                case DEVINFO_STR_NAME:                                                  strcpy(info->s, "CD/DA");                                       break;
338
 
                case DEVINFO_STR_FAMILY:                                        strcpy(info->s, "CD Audio");                            break;
339
 
                case DEVINFO_STR_VERSION:                                       strcpy(info->s, "1.0");                                         break;
340
 
                case DEVINFO_STR_SOURCE_FILE:                                           strcpy(info->s, __FILE__);                                      break;
341
 
                case DEVINFO_STR_CREDITS:                                       strcpy(info->s, "Copyright Nicola Salmoria and the MAME Team"); break;
342
 
        }
343
 
}
344
 
 
345
 
 
346
 
DEFINE_LEGACY_SOUND_DEVICE(CDDA, cdda);