~ubuntu-branches/ubuntu/breezy/kdemultimedia/breezy

« back to all changes in this revision

Viewing changes to kscd/libwm/plat_sun_cdda.c

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2005-03-24 04:48:58 UTC
  • mfrom: (1.2.1 upstream) (2.1.1 sarge)
  • Revision ID: james.westby@ubuntu.com-20050324044858-8ff88o9jxej6ii3d
Tags: 4:3.4.0-0ubuntu3
Add kubuntu_02_hide_arts_menu_entries.diff to hide artsbuilder and artscontrol k-menu entries

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * $Id: plat_sun_cdda.c,v 1.4 2000/10/16 08:01:08 dfoerste Exp $
 
2
 * $Id: plat_sun_cdda.c,v 1.9 2004/09/17 18:37:54 aseigo Exp $
3
3
 *
4
4
 * This file is part of WorkMan, the civilized CD player library
5
5
 * (c) 1991-1997 by Steven Grimm (original author)
25
25
 * Sun (really Solaris) CDDA functions.
26
26
 */
27
27
 
28
 
#include "include/wm_config.h"
29
 
 
30
 
static char plat_sun_cdda_id[] = "$Id: plat_sun_cdda.c,v 1.4 2000/10/16 08:01:08 dfoerste Exp $";
31
 
#if defined(sun) || defined(__sun__) && defined(SYSV) && defined(BUILD_CDDA) && defined(WMCDDA_DONE) /* { */
32
 
 
33
 
 
34
 
#include "include/wm_cdda.h"
35
 
/* types.h and cdio.h are included by wmcdda.h */
 
28
#include "include/wm_cdda.h"
 
29
 
 
30
#if defined(sun) || defined(__sun__) && defined(SYSV) && defined(BUILD_CDDA)
 
31
 
 
32
 
 
33
#include "include/wm_struct.h"
 
34
#include "include/wm_cdda.h"
 
35
/* types.h and cdio.h are included by wm_cdda.h */
36
36
 
37
37
#include <stdio.h>
38
38
#include <math.h>
81
81
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
82
82
};
83
83
 
 
84
static long wmcdda_normalize(struct cdda_block *block);
 
85
 
84
86
/*
85
87
 * Initialize the CDDA data buffer and open the appropriate device.
86
88
 *
92
94
 * need to exit right away so the UI doesn't show the user any CDDA controls.
93
95
 */
94
96
int
95
 
wmcdda_init(char **bufadr, long *buflenadr, int init_fd, char *devname)
 
97
wmcdda_init(struct cdda_device* pdev, struct cdda_block *block)
96
98
{
97
 
        struct cdrom_cdda       cdda;
98
 
 
99
 
        *bufadr = malloc(numblocks * CDDABLKSIZE * 2);
100
 
        if (*bufadr == NULL)
101
 
                return (-1);
102
 
 
103
 
        *buflenadr = numblocks * CDDABLKSIZE;
104
 
 
105
 
        /*init_fd = open(devname, 0);
106
 
        if (init_fd == -1)
107
 
                init_fd = open("/dev/rdsk/c0t6d0s2", 0);
108
 
        */
109
 
        init_fd = wmcdda_open(devname);
110
 
 
111
 
        if (init_fd > -1)
 
99
  struct cdrom_cdda     cdda;
 
100
  int i;
 
101
 
 
102
  if (pdev->fd > -1)
 
103
    return -1;
 
104
    
 
105
  for (i = 0; i < pdev->numblocks; i++) {
 
106
    /* in Linux const */
 
107
    pdev->blocks[i].buflen = pdev->frames_at_once * CDDABLKSIZE;
 
108
    pdev->blocks[i].buf = malloc(pdev->blocks[i].buflen);
 
109
    if (!pdev->blocks[i].buf)
 
110
      return -ENOMEM;
 
111
  }
 
112
 
 
113
  pdev->fd = open(pdev->devname, 0);
 
114
  if (pdev->fd == -1)
 
115
    pdev->fd = open("/dev/rdsk/c0t6d0s2", 0);
 
116
 
 
117
        if (pdev->fd > -1)
112
118
        {
113
119
                cdda.cdda_addr = 200;
114
120
                cdda.cdda_length = 1;
115
 
                cdda.cdda_data = *bufadr;
 
121
                cdda.cdda_data = pdev->blocks[0].buf;
116
122
                cdda.cdda_subcode = CDROM_DA_SUBQ;
117
123
 
118
 
                if (ioctl(init_fd, CDROMCDDA, &cdda) < 0)
 
124
                if (ioctl(pdev->fd, CDROMCDDA, &cdda) < 0)
119
125
                {
120
 
                        close(init_fd);
121
 
                        init_fd = -1;
 
126
                        block->status = WM_CDM_STOPPED;
 
127
                        return -1;
 
128
                } else {
 
129
                  block->status = WM_CDM_STOPPED;
 
130
                  return 0;
122
131
                }
 
132
        } else {
 
133
            block->status = WM_CDM_EJECTED;
 
134
            return -1;
123
135
        }
124
 
 
125
 
        return (init_fd);
126
 
}
127
 
 
128
 
/*
129
 
 * Try to open the CD device
130
 
 */
131
 
int
132
 
wmcdda_open(char *devname)
133
 
{
134
 
    int fd;
135
 
 
136
 
    fd = open(devname, 0); 
137
 
    if (fd == -1)
138
 
        fd = open("/dev/rdsk/c0t6d0s2", 0);
139
 
 
140
 
    return(fd);
141
 
}
142
 
 
 
136
}
143
137
 
144
138
/*
145
139
 * Close the CD-ROM device in preparation for exiting.
146
140
 */
147
 
void
148
 
wmcdda_close(int fd)
 
141
int
 
142
wmcdda_close(struct cdda_device* pdev)
149
143
{
150
 
        close(fd);
 
144
    int i;
 
145
 
 
146
    if(-1 == pdev->fd)
 
147
        return -1;
 
148
 
 
149
    close(pdev->fd);
 
150
    pdev->fd = -1;
 
151
    
 
152
    for (i = 0; i < pdev->numblocks; i++) {
 
153
        free(pdev->blocks[i].buf);
 
154
        pdev->blocks[i].buf = 0;
 
155
        pdev->blocks[i].buflen = 0;
 
156
    }
 
157
 
 
158
    return 0;
151
159
}
152
160
 
153
161
/*
154
162
 * Set up for playing the CD.  Actually this doesn't play a thing, just sets a
155
163
 * couple variables so we'll know what to do when we're called.
156
164
 */
157
 
void
 
165
int
158
166
wmcdda_setup(int start, int end, int realstart)
159
167
{
160
168
        current_position = start - 150;
167
175
         */
168
176
        if (direction == -1 && start == realstart)
169
177
                current_position = ending_position - numblocks;
 
178
  return 0;
170
179
}
171
180
 
172
181
/*
175
184
 * Returns number of bytes read, -1 on error, 0 if stopped for a benign reason.
176
185
 */
177
186
long
178
 
wmcdda_read(int fd, unsigned char *rawbuf, long buflen,
179
 
        struct cdda_block *block)
 
187
wmcdda_read(struct cdda_device* pdev, struct cdda_block *block)
180
188
{
181
 
        struct cdrom_cdda       cdda;
182
 
        int                     blk;
183
 
        unsigned char           *q;
184
 
        extern int              speed;
185
 
 
186
 
        if ((direction > 0 && current_position >= ending_position) ||
187
 
            (direction < 0 && current_position < starting_position))
188
 
        {
189
 
                block->status = WMCDDA_DONE;
190
 
                return (0);
191
 
        }
192
 
 
193
 
        cdda.cdda_addr = current_position;
194
 
        if (ending_position && current_position + numblocks > ending_position)
195
 
                cdda.cdda_length = ending_position - current_position;
196
 
        else
197
 
                cdda.cdda_length = numblocks;
198
 
        cdda.cdda_data = rawbuf;
199
 
        cdda.cdda_subcode = CDROM_DA_SUBQ;
200
 
 
201
 
        if (ioctl(fd, CDROMCDDA, &cdda) < 0)
202
 
        {
203
 
                if (errno == ENXIO)     /* CD ejected! */
204
 
                {
205
 
                        block->status = WMCDDA_EJECTED;
206
 
                        return (-1);
207
 
                }
208
 
 
209
 
                if (current_position + numblocks > ending_position)
210
 
                {
211
 
                        /*
212
 
                         * Hit the end of the CD, probably.
213
 
                         */
214
 
                        block->status = WMCDDA_DONE;
215
 
                        return (0);
216
 
                }
217
 
 
218
 
                /* Sometimes it fails once, dunno why */
219
 
                if (ioctl(fd, CDROMCDDA, &cdda) < 0)
220
 
                {
221
 
                        if (ioctl(fd, CDROMCDDA, &cdda) < 0)
222
 
                        {
223
 
                                if (ioctl(fd, CDROMCDDA, &cdda) < 0)
224
 
                                {
225
 
                                        perror("CDROMCDDA");
226
 
                                        block->status = WMCDDA_ERROR;
227
 
                                        return (-1);
228
 
                                }
229
 
                        }
230
 
                }
231
 
        }
232
 
 
233
 
        if (speed > 148)
234
 
        {
235
 
                /*
236
 
                 * We want speed=148 to advance by cdda_length, but
237
 
                 * speed=256 to advance cdda_length * 4.
238
 
                 */
239
 
                current_position = current_position +
240
 
                        (cdda.cdda_length * direction * (speed - 112)) / 36;
241
 
        }
242
 
        else
243
 
                current_position = current_position +
244
 
                        cdda.cdda_length * direction;
245
 
 
246
 
        for (blk = 0; blk < numblocks; blk++)
247
 
        {
248
 
                /*
249
 
                 * New valid Q-subchannel information?  Update the block
250
 
                 * status.
251
 
                 */
252
 
                q = &rawbuf[blk * CDDABLKSIZE + SAMPLES_PER_BLK * 4];
253
 
                if (*q == 1)
254
 
                {
255
 
                        block->status = WMCDDA_OK;
256
 
                        block->track =  unbcd[q[1]];
257
 
                        block->index =  unbcd[q[2]];
258
 
                        block->minute = unbcd[q[7]];
259
 
                        block->second = unbcd[q[8]];
260
 
                        block->frame =  unbcd[q[9]];
261
 
                }
262
 
        }
263
 
 
264
 
        return (cdda.cdda_length * CDDABLKSIZE);
 
189
    struct cdrom_cdda   cdda;
 
190
    int                 blk;
 
191
    unsigned char       *q;
 
192
    extern int          speed;
 
193
    unsigned char*      rawbuf = block->buf;
 
194
 
 
195
    if(pdev->fd < 0 && (wmcdda_init(pdev, block) < 0)) {
 
196
        return -1;
 
197
    }
 
198
 
 
199
    /*
 
200
     * Hit the end of the CD, probably.
 
201
     */
 
202
    if ((direction > 0 && current_position >= ending_position) ||
 
203
        (direction < 0 && current_position < starting_position))
 
204
    {
 
205
        block->status = WM_CDM_TRACK_DONE;
 
206
        return (0);
 
207
    }
 
208
 
 
209
    cdda.cdda_addr = current_position;
 
210
    if (ending_position && current_position + pdev->frames_at_once > ending_position)
 
211
        cdda.cdda_length = ending_position - current_position;
 
212
    else
 
213
        cdda.cdda_length = pdev->frames_at_once;
 
214
    cdda.cdda_data = (unsigned char*)block->buf;
 
215
    cdda.cdda_subcode = CDROM_DA_SUBQ;
 
216
 
 
217
    if (ioctl(pdev->fd, CDROMCDDA, &cdda) < 0)
 
218
    {
 
219
        if (errno == ENXIO)     /* CD ejected! */
 
220
        {
 
221
            block->status = WM_CDM_EJECTED;
 
222
            return (-1);
 
223
        }
 
224
 
 
225
        /* Sometimes it fails once, dunno why */
 
226
        if (ioctl(pdev->fd, CDROMCDDA, &cdda) < 0)
 
227
        {
 
228
            if (ioctl(pdev->fd, CDROMCDDA, &cdda) < 0)
 
229
            {
 
230
                if (ioctl(pdev->fd, CDROMCDDA, &cdda) < 0)
 
231
                {
 
232
                    perror("CDROMCDDA");
 
233
                    block->status = WM_CDM_CDDAERROR;
 
234
                    return (-1);
 
235
                }
 
236
            }
 
237
        }
 
238
    }
 
239
 
 
240
    if (speed > 148)
 
241
    {
 
242
        /*
 
243
         * We want speed=148 to advance by cdda_length, but
 
244
         * speed=256 to advance cdda_length * 4.
 
245
         */
 
246
        current_position = current_position +
 
247
            (cdda.cdda_length * direction * (speed - 112)) / 36;
 
248
    }
 
249
    else
 
250
        current_position = current_position + cdda.cdda_length * direction;
 
251
 
 
252
    for (blk = 0; blk < numblocks; blk++)
 
253
    {
 
254
        /*
 
255
         * New valid Q-subchannel information?  Update the block
 
256
         * status.
 
257
         */
 
258
        q = &rawbuf[blk * CDDABLKSIZE + SAMPLES_PER_BLK * 4];
 
259
        if (*q == 1)
 
260
        {
 
261
            block->track =  unbcd[q[1]];
 
262
            block->index =  unbcd[q[2]];
 
263
            /*block->minute = unbcd[q[7]];
 
264
            block->second = unbcd[q[8]];*/
 
265
            block->frame =  unbcd[q[9]];
 
266
            block->status = WM_CDM_PLAYING;
 
267
            block->buflen = cdda.cdda_length;
 
268
        }
 
269
    }
 
270
 
 
271
    return wmcdda_normalize(block);
265
272
}
266
273
 
267
274
/*
274
281
 * XXX - do byte swapping on Intel boxes?
275
282
 */
276
283
long
277
 
wmcdda_normalize(unsigned char *rawbuf, long buflen, struct cdda_block *block)
 
284
wmcdda_normalize(struct cdda_block *block)
278
285
{
279
286
        int             i, nextq;
 
287
        long buflen = block->buflen;
280
288
        int             blocks = buflen / CDDABLKSIZE;
 
289
        unsigned char *rawbuf = block->buf;
281
290
        unsigned char   *dest = rawbuf;
282
291
        unsigned char   tmp;
283
292
        long            *buf32 = (long *)rawbuf, tmp32;