summaryrefslogtreecommitdiff
path: root/apps/metadata.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/metadata.c')
-rw-r--r--apps/metadata.c130
1 files changed, 90 insertions, 40 deletions
diff --git a/apps/metadata.c b/apps/metadata.c
index b57bf0fbc7..2883b01407 100644
--- a/apps/metadata.c
+++ b/apps/metadata.c
@@ -798,6 +798,95 @@ static bool get_flac_metadata(int fd, struct mp3entry* id3)
798 return true; 798 return true;
799} 799}
800 800
801static bool get_wave_metadata(int fd, struct mp3entry* id3)
802{
803 /* Use the trackname part of the id3 structure as a temporary buffer */
804 unsigned char* buf = id3->path;
805 unsigned long totalsamples = 0;
806 unsigned long channels = 0;
807 unsigned long bitspersample = 0;
808 unsigned long numbytes = 0;
809 int read_bytes;
810 int i;
811
812 if ((lseek(fd, 0, SEEK_SET) < 0)
813 || ((read_bytes = read(fd, buf, sizeof(id3->path))) < 44))
814 {
815 return false;
816 }
817
818 if ((memcmp(buf, "RIFF",4) != 0)
819 || (memcmp(&buf[8], "WAVE", 4) !=0 ))
820 {
821 return false;
822 }
823
824 buf += 12;
825 read_bytes -= 12;
826
827 while ((numbytes == 0) && (read_bytes >= 8))
828 {
829 /* chunkSize */
830 i = get_long(&buf[4]);
831
832 if (memcmp(buf, "fmt ", 4) == 0)
833 {
834 /* skipping wFormatTag */
835 /* wChannels */
836 channels = buf[10] | (buf[11] << 8);
837 /* dwSamplesPerSec */
838 id3->frequency = get_long(&buf[12]);
839 /* dwAvgBytesPerSec */
840 id3->bitrate = (get_long(&buf[16]) * 8) / 1000;
841 /* skipping wBlockAlign */
842 /* wBitsPerSample */
843 bitspersample = buf[22] | (buf[23] << 8);
844 }
845 else if (memcmp(buf, "data", 4) == 0)
846 {
847 numbytes = i;
848 }
849 else if (memcmp(buf, "fact", 4) == 0)
850 {
851 /* dwSampleLength */
852 if (i >= 4)
853 {
854 totalsamples = get_long(&buf[8]);
855 }
856 }
857
858 /* go to next chunk (even chunk sizes must be padded) */
859 if (i & 0x01)
860 {
861 i++;
862 }
863
864 buf += i + 8;
865 read_bytes -= i + 8;
866 }
867
868 if ((numbytes == 0) || (channels == 0))
869 {
870 return false;
871 }
872
873 if (totalsamples == 0)
874 {
875 /* for PCM only */
876 totalsamples = numbytes
877 / ((((bitspersample - 1) / 8) + 1) * channels);
878 }
879
880 id3->vbr = false; /* All WAV files are CBR */
881 id3->filesize = filesize(fd);
882
883 /* Calculate track length (in ms) and estimate the bitrate (in kbit/s) */
884 id3->length = (totalsamples / id3->frequency) * 1000;
885
886 return true;
887}
888
889
801/* Simple file type probing by looking at the filename extension. */ 890/* Simple file type probing by looking at the filename extension. */
802unsigned int probe_file_format(const char *filename) 891unsigned int probe_file_format(const char *filename)
803{ 892{
@@ -832,10 +921,6 @@ bool get_metadata(struct track_info* track, int fd, const char* trackname,
832{ 921{
833 unsigned char* buf; 922 unsigned char* buf;
834 unsigned long totalsamples; 923 unsigned long totalsamples;
835 unsigned long bytespersample;
836 unsigned long channels;
837 unsigned long bitspersample;
838 unsigned long numbytes;
839 int bytesperframe; 924 int bytesperframe;
840 int i; 925 int i;
841 926
@@ -870,46 +955,11 @@ bool get_metadata(struct track_info* track, int fd, const char* trackname,
870 break; 955 break;
871 956
872 case AFMT_PCM_WAV: 957 case AFMT_PCM_WAV:
873 /* Use the trackname part of the id3 structure as a temporary buffer */ 958 if (!get_wave_metadata(fd, &(track->id3)))
874 buf = track->id3.path;
875
876 if ((lseek(fd, 0, SEEK_SET) < 0) || (read(fd, buf, 44) < 44))
877 { 959 {
878 return false; 960 return false;
879 } 961 }
880 962
881 if ((memcmp(buf,"RIFF",4) !=0 )
882 || (memcmp(&buf[8], "WAVEfmt", 7) !=0 ))
883 {
884 logf("Not a WAV: %s\n", trackname);
885 return false;
886 }
887
888 /* FIX: Correctly parse WAV header - we assume canonical
889 * 44-byte header
890 */
891
892 bitspersample = buf[34];
893 channels = buf[22];
894
895 if ((bitspersample != 16) || (channels != 2))
896 {
897 logf("Unsupported WAV - %d bps, %d channels\n",
898 bitspersample, channels);
899 return false;
900 }
901
902 bytespersample = ((bitspersample / 8) * channels);
903 numbytes = get_long(&buf[40]);
904 totalsamples = numbytes / bytespersample;
905
906 track->id3.vbr = false; /* All WAV files are CBR */
907 track->id3.filesize = filesize(fd);
908 track->id3.frequency = get_long(&buf[24]);
909
910 /* Calculate track length (in ms) and estimate the bitrate (in kbit/s) */
911 track->id3.length = (totalsamples / track->id3.frequency) * 1000;
912 track->id3.bitrate = (track->id3.frequency * bytespersample) / (1000 / 8);
913 break; 963 break;
914 964
915 case AFMT_WAVPACK: 965 case AFMT_WAVPACK: