00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "libtremorplugin.h"
00023
00024
00025 #include <opie2/odebug.h>
00026
00027
00028 #include <qmap.h>
00029
00030
00031 #include <stdio.h>
00032 #include <stdarg.h>
00033 #include <stdlib.h>
00034 #include <sys/types.h>
00035 #include <sys/stat.h>
00036 #include <fcntl.h>
00037 #include <unistd.h>
00038 #include <string.h>
00039 #include <errno.h>
00040 #include <time.h>
00041 #include <locale.h>
00042 #include <math.h>
00043 #include <assert.h>
00044
00045
00046 extern "C" {
00047 #include "tremor/ivorbisfile.h"
00048 }
00049
00050
00051 #define MPEG_BUFFER_SIZE 65536
00052
00053 #define debugMsg(a)
00054
00055
00056 class LibTremorPluginData {
00057 public:
00058 char* filename;
00059 FILE* f;
00060 OggVorbis_File vf;
00061 vorbis_info* vi;
00062 vorbis_comment* vc;
00063 bool bos;
00064 int csection;
00065 QString finfo;
00066 };
00067
00068
00069 LibTremorPlugin::LibTremorPlugin() {
00070 odebug << "<<<<<<<<<<<<<TREMOR!!!!!>>>>>>>>>>>>>>>>>>" << oendl;
00071 d = new LibTremorPluginData;
00072 d->f = 0;
00073 d->vi = 0;
00074 d->vc = 0;
00075 d->bos = 0;
00076 d->csection = 0;
00077 d->finfo = "";
00078 }
00079
00080
00081 LibTremorPlugin::~LibTremorPlugin() {
00082 close();
00083 delete d;
00084 }
00085
00086
00087 bool LibTremorPlugin::isFileSupported( const QString& path ) {
00088 debugMsg( "LibTremorPlugin::isFileSupported" );
00089
00090
00091
00092
00093
00094
00095 char *ext = strrchr( path.latin1(), '.' );
00096
00097
00098 if ( ext ) {
00099 if ( strncasecmp(ext, ".ogg", 4) == 0 )
00100 return TRUE;
00101 }
00102
00103 return FALSE;
00104 }
00105
00106
00107 bool LibTremorPlugin::open( const QString& path ) {
00108 debugMsg( "LibTremorPlugin::open" );
00109
00110 d->filename = (char*) path.latin1();
00111 d->f = fopen( d->filename, "r" );
00112 if (d->f == 0) {
00113 odebug << "error opening " << d->filename << "" << oendl;
00114 return FALSE;
00115 }
00116
00117 if (ov_open(d->f, &d->vf, NULL, 0) < 0) {
00118 odebug << "error opening " << d->filename << "" << oendl;
00119 return FALSE;
00120 }
00121
00122 d->vc = ov_comment(&d->vf, -1);
00123 d->vi = ov_info(&d->vf, -1);
00124 d->bos = false;
00125
00126 QString comments[] = { "title", "artist", "album", "year", "tracknumber", "" };
00127 QString cdescr[] = { "Title", "Artist", "Album", "Year", "Track", "" };
00128
00129
00130 QMap<QString, QString> cmap;
00131 char** cptr = d->vc->user_comments;
00132
00133 while (*cptr != 0) {
00134 QString s(*cptr);
00135 int n = s.find('=');
00136
00137 if (n < 0) {
00138 continue;
00139 }
00140
00141 QString key = s.left(n).lower();
00142 QString value = s.mid(n+1);
00143
00144 cmap[key] = value;
00145 cptr++;
00146 }
00147
00148 d->finfo = "";
00149 for(int i = 0; !comments[i].isEmpty(); i++) {
00150 QString v = cmap[comments[i].lower()];
00151
00152 if (!v.isEmpty()) {
00153 if (!d->finfo.isEmpty()) {
00154 d->finfo += ", ";
00155 }
00156
00157 d->finfo += cdescr[i] + ": " + v;
00158 }
00159 }
00160
00161 odebug << "finfo: " + d->finfo << oendl;
00162
00163 return TRUE;
00164 }
00165
00166
00167 bool LibTremorPlugin::close() {
00168 debugMsg( "LibTremorPlugin::close" );
00169
00170 int result = TRUE;
00171
00172 if (fclose(d->f) == -1) {
00173 odebug << "error closing file " << d->filename << "" << oendl;
00174 result = FALSE;
00175 }
00176
00177 d->f = 0;
00178 d->finfo = "";
00179
00180 return result;
00181 }
00182
00183
00184 bool LibTremorPlugin::isOpen() {
00185 debugMsg( "LibTremorPlugin::isOpen" );
00186 return ( d->f != 0 );
00187 }
00188
00189
00190 const QString &LibTremorPlugin::fileInfo() {
00191 return d->finfo;
00192 }
00193
00194 int LibTremorPlugin::audioStreams() {
00195 debugMsg( "LibTremorPlugin::audioStreams" );
00196 return 1;
00197 }
00198
00199
00200 int LibTremorPlugin::audioChannels( int ) {
00201 odebug << "LibTremorPlugin::audioChannels: " << d->vi->channels << "" << oendl;
00202 return d->vi->channels;
00203 }
00204
00205
00206 int LibTremorPlugin::audioFrequency( int ) {
00207 odebug << "LibTremorPlugin::audioFrequency: " << d->vi->rate << "" << oendl;
00208 return d->vi->rate;
00209 }
00210
00211
00212 int LibTremorPlugin::audioSamples( int ) {
00213 debugMsg( "LibTremorPlugin::audioSamples" );
00214 return (int) ov_pcm_total(&d->vf,-1);
00215 }
00216
00217
00218 bool LibTremorPlugin::audioSetSample( long, int ) {
00219 debugMsg( "LibTremorPlugin::audioSetSample" );
00220 return FALSE;
00221 }
00222
00223
00224 long LibTremorPlugin::audioGetSample( int ) {
00225 debugMsg( "LibTremorPlugin::audioGetSample" );
00226 return 0;
00227 }
00228
00229
00230 bool LibTremorPlugin::audioReadSamples( short *output, int, long samples, long& samplesMade, int ) {
00231
00232
00233 int old_section = d->csection;
00234
00235 char* buf = (char*) output;
00236 int length = samples * 4;
00237
00238 if ( samples == 0 )
00239 return false;
00240
00241 while (length > 0) {
00242 if (d->bos) {
00243 d->vi = ov_info(&d->vf, -1);
00244 d->vc = ov_comment(&d->vf, -1);
00245 }
00246
00247 int n = 4096;
00248 if (length < n) {
00249 n = length;
00250 }
00251
00252 long ret = ov_read(&d->vf, buf, n, &d->csection);
00253
00254 if (ret == 0) {
00255 break;
00256 } else if (ret < 0) {
00257 return true;
00258 }
00259
00260 if (old_section != d->csection) {
00261 d->bos = true;
00262 }
00263
00264 buf += ret;
00265 length -= ret;
00266
00267 }
00268
00269 samplesMade = samples;
00270
00271 return true;
00272 }
00273
00274 double LibTremorPlugin::getTime() {
00275 debugMsg( "LibTremorPlugin::getTime" );
00276 return 0.0;
00277 }
00278