1 /* EasyTAG - Tag editor for audio files.
2 * Copyright (C) 2014-2015 David King <amigadave@amigadave.com>
3 * Copyright (C) 2007 Maarten Maathuis (madman2003@gmail.com)
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20 #include "config.h"
21
22 #ifdef ENABLE_WAVPACK
23
24 #include <glib/gi18n.h>
25 #include <wavpack/wavpack.h>
26
27 #include "et_core.h"
28 #include "misc.h"
29 #include "wavpack_header.h"
30 #include "wavpack_private.h"
31
32
33 gboolean
et_wavpack_header_read_file_info(GFile * file,ET_File_Info * ETFileInfo,GError ** error)34 et_wavpack_header_read_file_info (GFile *file,
35 ET_File_Info *ETFileInfo,
36 GError **error)
37 {
38 WavpackStreamReader reader = { wavpack_read_bytes, wavpack_get_pos,
39 wavpack_set_pos_abs, wavpack_set_pos_rel,
40 wavpack_push_back_byte, wavpack_get_length,
41 wavpack_can_seek, NULL /* No writing. */ };
42 EtWavpackState state;
43 WavpackContext *wpc;
44 gchar message[80];
45
46 g_return_val_if_fail (file != NULL && ETFileInfo != NULL, FALSE);
47 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
48
49 state.error = NULL;
50 state.istream = g_file_read (file, NULL, &state.error);
51
52 if (!state.istream)
53 {
54 g_propagate_error (error, state.error);
55 return FALSE;
56 }
57
58 state.seekable = G_SEEKABLE (state.istream);
59
60 /* NULL for the WavPack correction file. */
61 wpc = WavpackOpenFileInputEx (&reader, &state, NULL, message, 0, 0);
62
63 if (wpc == NULL)
64 {
65 if (state.error)
66 {
67 g_propagate_error (error, state.error);
68 }
69 else
70 {
71 g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "%s",
72 message);
73 }
74
75 g_object_unref (state.istream);
76 return FALSE;
77 }
78
79 ETFileInfo->version = WavpackGetVersion(wpc);
80 /* .wvc correction file not counted */
81 ETFileInfo->bitrate = WavpackGetAverageBitrate(wpc, 0)/1000;
82 ETFileInfo->samplerate = WavpackGetSampleRate(wpc);
83 ETFileInfo->mode = WavpackGetNumChannels(wpc);
84 ETFileInfo->layer = WavpackGetChannelMask (wpc);
85 ETFileInfo->size = WavpackGetFileSize(wpc);
86 ETFileInfo->duration = WavpackGetNumSamples(wpc)/ETFileInfo->samplerate;
87
88 WavpackCloseFile(wpc);
89
90 g_object_unref (state.istream);
91
92 return TRUE;
93 }
94
95 /*
96 * et_wavpack_channel_mask_to_string:
97 * @channels: total number of channels
98 * @mask: Microsoft channel mask
99 *
100 * Formats a number of channels and a channel mask into a string, suitable for
101 * display to the user.
102 *
103 * Returns: the formatted channel information
104 */
105 static gchar *
et_wavpack_channel_mask_to_string(gint channels,gint mask)106 et_wavpack_channel_mask_to_string (gint channels,
107 gint mask)
108 {
109 gboolean lfe;
110
111 /* Low frequency effects channel is bit 3. */
112 lfe = mask & (1 << 3);
113
114 if (lfe)
115 {
116 return g_strdup_printf ("%d.1", channels - 1);
117 }
118 else
119 {
120 return g_strdup_printf ("%d", channels);
121 }
122 }
123
124 EtFileHeaderFields *
et_wavpack_header_display_file_info_to_ui(const ET_File * ETFile)125 et_wavpack_header_display_file_info_to_ui (const ET_File *ETFile)
126 {
127 EtFileHeaderFields *fields;
128 ET_File_Info *info;
129 gchar *time = NULL;
130 gchar *time1 = NULL;
131 gchar *size = NULL;
132 gchar *size1 = NULL;
133
134 info = ETFile->ETFileInfo;
135 fields = g_slice_new (EtFileHeaderFields);
136
137 fields->description = _("Wavpack File");
138
139 /* Encoder version */
140 fields->version_label = _("Encoder:");
141 fields->version = g_strdup_printf ("%d", info->version);
142
143 /* Bitrate */
144 fields->bitrate = g_strdup_printf (_("%d kb/s"), info->bitrate);
145
146 /* Samplerate */
147 fields->samplerate = g_strdup_printf (_("%d Hz"), info->samplerate);
148
149 /* Mode */
150 fields->mode_label = _("Channels:");
151 fields->mode = et_wavpack_channel_mask_to_string (info->mode,
152 info->layer);
153
154 /* Size */
155 size = g_format_size (info->size);
156 size1 = g_format_size (ETCore->ETFileDisplayedList_TotalSize);
157 fields->size = g_strdup_printf ("%s (%s)", size, size1);
158 g_free (size);
159 g_free (size1);
160
161 /* Duration */
162 time = Convert_Duration (info->duration);
163 time1 = Convert_Duration (ETCore->ETFileDisplayedList_TotalDuration);
164 fields->duration = g_strdup_printf ("%s (%s)", time, time1);
165 g_free (time);
166 g_free (time1);
167
168 return fields;
169 }
170
171 void
et_wavpack_file_header_fields_free(EtFileHeaderFields * fields)172 et_wavpack_file_header_fields_free (EtFileHeaderFields *fields)
173 {
174 g_return_if_fail (fields != NULL);
175
176 g_free (fields->version);
177 g_free (fields->bitrate);
178 g_free (fields->samplerate);
179 g_free (fields->mode);
180 g_free (fields->size);
181 g_free (fields->duration);
182 g_slice_free (EtFileHeaderFields, fields);
183 }
184
185 #endif /* ENABLE_WAVPACK */
186