Remove trailing whitespace throughout the source tree.
[herrie-working.git] / herrie / src / audio_file.c
blob64d2783888b3b526eed51da078640015d9a1d319
1 /*
2 * Copyright (c) 2006-2011 Ed Schouten <ed@80386.nl>
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
26 /**
27 * @file audio_file.c
28 * @brief Generic access and decoding of audio file formats.
31 #include "stdinc.h"
33 #include "audio_file.h"
34 #include "audio_format.h"
35 #include "scrobbler.h"
36 #include "vfs.h"
38 /**
39 * @brief Audio format containg its functions to open, close, read and
40 * seek the format.
42 struct audio_format {
43 /**
44 * @brief The format's open call.
46 int (*open)(struct audio_file *fd, const char *ext);
47 /**
48 * @brief The format's close call.
50 void (*close)(struct audio_file *fd);
51 /**
52 * @brief The format's read call.
54 size_t (*read)(struct audio_file *fd, int16_t *buf, size_t len);
55 /**
56 * @brief The format's seek call.
58 void (*seek)(struct audio_file *fd, int len, int rel);
62 * Make sure you add the most strict matching formats at the top. Raw or
63 * headerless file formats should be listed at the bottom, as the
64 * matching code just runs through this list.
66 /**
67 * @brief List of audio formats.
69 static struct audio_format formats[] = {
70 #ifdef BUILD_VORBIS
71 { vorbis_open, vorbis_close, vorbis_read, vorbis_seek },
72 #endif /* !BUILD_VORBIS */
73 #ifdef BUILD_MP3
74 { mp3_open, mp3_close, mp3_read, mp3_seek },
75 #endif /* !BUILD_MP3 */
76 #ifdef BUILD_MODPLUG
77 { modplug_open, modplug_close, modplug_read, modplug_seek },
78 #endif /* !BUILD_MODPLUG */
79 #ifdef BUILD_SNDFILE
81 * Keep this entry at the bottom - it does evil stuff with raw
82 * file descriptors. It could also catch some raw formats.
84 { sndfile_open, sndfile_close, sndfile_read, sndfile_seek },
85 #endif /* !BUILD_SNDFILE */
87 /**
88 * @brief Amount of audio formats.
90 #define NUM_FORMATS (sizeof formats / sizeof(struct audio_format))
92 struct audio_file *
93 audio_file_open(const struct vfsref *vr)
95 const char *ext;
96 struct audio_file *out = NULL;
97 unsigned int i;
99 out = g_slice_new0(struct audio_file);
101 out->fp = vfs_open(vr);
102 if (out->fp == NULL)
103 goto bad;
105 /* Store file extension */
106 if ((ext = strrchr(vfs_filename(vr), '.')) != NULL)
107 ext++;
109 for (i = 0; i < NUM_FORMATS; i++) {
110 if (fseek(out->fp, 0, SEEK_SET) != 0)
111 out->stream = 1;
113 if (formats[i].open(out, ext) == 0) {
114 /* Assign the format to the file */
115 out->drv = &formats[i];
116 break;
120 if (out->drv == NULL) {
121 /* No matched format */
122 fclose(out->fp);
123 goto bad;
126 /* No tag - just use the display name then */
127 if (out->title == NULL)
128 out->title = g_strdup(vfs_name(vr));
130 return (out);
132 bad:
133 g_slice_free(struct audio_file, out);
134 return (NULL);
137 void
138 audio_file_close(struct audio_file *fd)
140 fd->drv->close(fd);
141 if (fd->fp != NULL)
142 fclose(fd->fp);
144 g_free(fd->artist);
145 g_free(fd->title);
146 #ifdef BUILD_SCROBBLER
147 g_free(fd->album);
148 #endif /* BUILD_SCROBBLER */
149 g_slice_free(struct audio_file, fd);
152 size_t
153 audio_file_read(struct audio_file *fd, int16_t *buf, size_t len)
155 size_t ret;
157 ret = fd->drv->read(fd, buf, len);
158 #ifdef BUILD_SCROBBLER
159 scrobbler_notify_read(fd, (ret == 0));
160 #endif /* BUILD_SCROBBLER */
162 return (ret);
165 void
166 audio_file_seek(struct audio_file *fd, int len, int rel)
168 g_assert(len != 0 || rel == 0);
170 if (!fd->stream) {
171 fd->drv->seek(fd, len, rel);
172 #ifdef BUILD_SCROBBLER
173 scrobbler_notify_seek(fd);
174 #endif /* BUILD_SCROBBLER */