diff options
Diffstat (limited to 'apps/metadata.c')
-rw-r--r-- | apps/metadata.c | 130 |
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 | ||
801 | static 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. */ |
802 | unsigned int probe_file_format(const char *filename) | 891 | unsigned 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: |