1 /**
2  * \file tracks.c
3  * Example program to list the tracks on a device.
4  *
5  * Copyright (C) 2005-2012 Linus Walleij <triad@df.lth.se>
6  * Copyright (C) 2007 Ted Bullock <tbullock@canada.com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23 #include "common.h"
24 #include <stdlib.h>
25 
dump_trackinfo(LIBMTP_track_t * track)26 static void dump_trackinfo(LIBMTP_track_t *track)
27 {
28   printf("Track ID: %u\n", track->item_id);
29   if (track->title != NULL)
30     printf("   Title: %s\n", track->title);
31   if (track->artist != NULL)
32     printf("   Artist: %s\n", track->artist);
33   if (track->genre != NULL)
34     printf("   Genre: %s\n", track->genre);
35   if (track->composer != NULL)
36     printf("   Composer: %s\n", track->composer);
37   if (track->album != NULL)
38     printf("   Album: %s\n", track->album);
39   if (track->date != NULL)
40     printf("   Date: %s\n", track->date);
41   if (track->filename != NULL)
42     printf("   Origfilename: %s\n", track->filename);
43   printf("   Track number: %d\n", track->tracknumber);
44   printf("   Duration: %d milliseconds\n", track->duration);
45 #ifdef __WIN32__
46   printf("   File size %I64u bytes\n", track->filesize);
47 #else
48   printf("   File size %llu bytes\n", (long long unsigned int) track->filesize);
49 #endif
50   printf("   Filetype: %s\n", LIBMTP_Get_Filetype_Description(track->filetype));
51   if (track->samplerate != 0) {
52     printf("   Sample rate: %u Hz\n", track->samplerate);
53   }
54   if (track->nochannels != 0) {
55     printf("   Number of channels: %u\n", track->nochannels);
56   }
57   if (track->wavecodec != 0) {
58     printf("   WAVE fourCC code: 0x%08X\n", track->wavecodec);
59   }
60   if (track->bitrate != 0) {
61     printf("   Bitrate: %u bits/s\n", track->bitrate);
62   }
63   if (track->bitratetype != 0) {
64     if (track->bitratetype == 1) {
65       printf("   Bitrate type: Constant\n");
66     } else if (track->bitratetype == 2) {
67       printf("   Bitrate type: Variable (VBR)\n");
68     } else if (track->bitratetype == 3) {
69       printf("   Bitrate type: Free\n");
70     } else {
71       printf("   Bitrate type: Unknown/Erroneous value\n");
72     }
73   }
74   if (track->rating != 0) {
75     printf("   User rating: %u (out of 100)\n", track->rating);
76   }
77   if (track->usecount != 0) {
78     printf("   Use count: %u times\n", track->usecount);
79   }
80 }
81 
82 static void
dump_tracks(LIBMTP_mtpdevice_t * device,uint32_t storageid,int leaf)83 dump_tracks(LIBMTP_mtpdevice_t *device, uint32_t storageid, int leaf)
84 {
85   LIBMTP_file_t *files;
86 
87   /* Get track listing. */
88   files = LIBMTP_Get_Files_And_Folders(device,
89 				       storageid,
90 				       leaf);
91   if (files == NULL) {
92     LIBMTP_Dump_Errorstack(device);
93     LIBMTP_Clear_Errorstack(device);
94   } else {
95     LIBMTP_file_t *file, *tmp;
96 
97     file = files;
98     while (file != NULL) {
99       /* Please don't print these */
100       if (file->filetype == LIBMTP_FILETYPE_FOLDER) {
101 	dump_tracks(device, storageid, file->item_id);
102       } else if (LIBMTP_FILETYPE_IS_TRACK(file->filetype)) {
103 	LIBMTP_track_t *track;
104 
105 	track = LIBMTP_Get_Trackmetadata(device, file->item_id);
106 	dump_trackinfo(track);
107 	LIBMTP_destroy_track_t(track);
108       }
109       tmp = file;
110       file = file->next;
111       LIBMTP_destroy_file_t(tmp);
112     }
113   }
114 }
115 
main(int argc,char ** argv)116 int main (int argc, char **argv)
117 {
118   LIBMTP_raw_device_t *rawdevices;
119   int numrawdevices;
120   LIBMTP_error_number_t err;
121   int i;
122 
123   LIBMTP_Init();
124   fprintf(stdout, "Attempting to connect device(s)\n");
125 
126   err = LIBMTP_Detect_Raw_Devices(&rawdevices, &numrawdevices);
127   switch(err)
128   {
129   case LIBMTP_ERROR_NO_DEVICE_ATTACHED:
130     fprintf(stdout, "mtp-tracks: No Devices have been found\n");
131     return 0;
132   case LIBMTP_ERROR_CONNECTING:
133     fprintf(stderr, "mtp-tracks: There has been an error connecting. Exit\n");
134     return 1;
135   case LIBMTP_ERROR_MEMORY_ALLOCATION:
136     fprintf(stderr, "mtp-tracks: Memory Allocation Error. Exit\n");
137     return 1;
138 
139   /* Unknown general errors - This should never execute */
140   case LIBMTP_ERROR_GENERAL:
141   default:
142     fprintf(stderr, "mtp-tracks: Unknown error, please report "
143                     "this to the libmtp developers\n");
144   return 1;
145 
146   /* Successfully connected at least one device, so continue */
147   case LIBMTP_ERROR_NONE:
148     fprintf(stdout, "mtp-tracks: Successfully connected\n");
149     fflush(stdout);
150     break;
151   }
152 
153   /* Iterate through connected MTP devices */
154   for (i = 0; i < numrawdevices; i++) {
155     LIBMTP_mtpdevice_t *device;
156     LIBMTP_devicestorage_t *storage;
157     char *friendlyname;
158 
159     device = LIBMTP_Open_Raw_Device_Uncached(&rawdevices[i]);
160     if (device == NULL) {
161       fprintf(stderr, "Unable to open raw device %d\n", i);
162       continue;
163     }
164 
165     /* Echo the friendly name so we know which device we are working with */
166     friendlyname = LIBMTP_Get_Friendlyname(device);
167     if (friendlyname == NULL) {
168       printf("Friendly name: (NULL)\n");
169     } else {
170       printf("Friendly name: %s\n", friendlyname);
171       free(friendlyname);
172     }
173 
174     LIBMTP_Dump_Errorstack(device);
175     LIBMTP_Clear_Errorstack(device);
176 
177     /* Loop over storages */
178     for (storage = device->storage; storage != 0; storage = storage->next) {
179       dump_tracks(device, storage->id, LIBMTP_FILES_AND_FOLDERS_ROOT);
180     }
181 
182     LIBMTP_Release_Device(device);
183   }
184 
185   printf("OK.\n");
186   exit (0);
187 }
188 
189