Diffstat (limited to 'gammu/emb/common/service/gsmring.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | gammu/emb/common/service/gsmring.c | 45 |
1 files changed, 43 insertions, 2 deletions
diff --git a/gammu/emb/common/service/gsmring.c b/gammu/emb/common/service/gsmring.c index 7df46f1..dab028c 100644 --- a/gammu/emb/common/service/gsmring.c +++ b/gammu/emb/common/service/gsmring.c | |||
@@ -1,21 +1,24 @@ | |||
1 | /* (c) 2001-2004 by Marcin Wiacek */ | 1 | /* (c) 2001-2004 by Marcin Wiacek */ |
2 | /* Based on some work from Ralf Thelen (7110 ringtones), | 2 | /* Based on some work from Ralf Thelen (7110 ringtones) and others */ |
3 | * Gnokii (RTTL and SM) and others | 3 | /* Based on some work (RTTL and SM) from Gnokii (www.gnokii.org) |
4 | * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot | ||
5 | * GNU GPL version 2 or later | ||
4 | */ | 6 | */ |
5 | 7 | ||
6 | #include <stdlib.h> | 8 | #include <stdlib.h> |
7 | #include <string.h> | 9 | #include <string.h> |
8 | #include <ctype.h> | 10 | #include <ctype.h> |
9 | #include <math.h> | 11 | #include <math.h> |
12 | #include <sys/stat.h> | ||
10 | #ifdef WIN32 | 13 | #ifdef WIN32 |
11 | # include <windows.h> | 14 | # include <windows.h> |
12 | #endif | 15 | #endif |
13 | 16 | ||
14 | #include "../gsmcomon.h" | 17 | #include "../gsmcomon.h" |
15 | #include "../misc/coding/coding.h" | 18 | #include "../misc/coding/coding.h" |
16 | #include "../gsmstate.h" | 19 | #include "../gsmstate.h" |
17 | #include "gsmring.h" | 20 | #include "gsmring.h" |
18 | #include "sms/gsmsms.h" | 21 | #include "sms/gsmsms.h" |
19 | 22 | ||
20 | int GSM_RingNoteGetFrequency(GSM_RingNote Note) | 23 | int GSM_RingNoteGetFrequency(GSM_RingNote Note) |
21 | { | 24 | { |
@@ -147,24 +150,30 @@ static GSM_Error savebin(FILE *file, GSM_Ringtone *ringtone) | |||
147 | fwrite(&nullchar,1,1,file); | 150 | fwrite(&nullchar,1,1,file); |
148 | fwrite(&nullchar,1,1,file); | 151 | fwrite(&nullchar,1,1,file); |
149 | fwrite(ringtone->NokiaBinary.Frame,1,ringtone->NokiaBinary.Length,file); | 152 | fwrite(ringtone->NokiaBinary.Frame,1,ringtone->NokiaBinary.Length,file); |
150 | return ERR_NONE; | 153 | return ERR_NONE; |
151 | } | 154 | } |
152 | 155 | ||
153 | static GSM_Error savepuremidi(FILE *file, GSM_Ringtone *ringtone) | 156 | static GSM_Error savepuremidi(FILE *file, GSM_Ringtone *ringtone) |
154 | { | 157 | { |
155 | fwrite(ringtone->NokiaBinary.Frame,1,ringtone->NokiaBinary.Length,file); | 158 | fwrite(ringtone->NokiaBinary.Frame,1,ringtone->NokiaBinary.Length,file); |
156 | return ERR_NONE; | 159 | return ERR_NONE; |
157 | } | 160 | } |
158 | 161 | ||
162 | static GSM_Error savemmf(FILE *file, GSM_Ringtone *ringtone) | ||
163 | { | ||
164 | fwrite(ringtone->NokiaBinary.Frame,1,ringtone->NokiaBinary.Length,file); | ||
165 | return ERR_NONE; | ||
166 | } | ||
167 | |||
159 | GSM_Error saverttl(FILE *file, GSM_Ringtone *ringtone) | 168 | GSM_Error saverttl(FILE *file, GSM_Ringtone *ringtone) |
160 | { | 169 | { |
161 | GSM_RingNoteScaleDefNoteScale; | 170 | GSM_RingNoteScaleDefNoteScale; |
162 | GSM_RingNoteDurationDefNoteDuration; | 171 | GSM_RingNoteDurationDefNoteDuration; |
163 | 172 | ||
164 | GSM_RingNoteStyleDefNoteStyle=0; | 173 | GSM_RingNoteStyleDefNoteStyle=0; |
165 | int DefNoteTempo=0; | 174 | int DefNoteTempo=0; |
166 | 175 | ||
167 | bool started = false, firstcomma = true; | 176 | bool started = false, firstcomma = true; |
168 | GSM_RingNote *Note; | 177 | GSM_RingNote *Note; |
169 | 178 | ||
170 | unsigned char buffer[15]; | 179 | unsigned char buffer[15]; |
@@ -476,24 +485,27 @@ GSM_Error GSM_SaveRingtoneFile(char *FileName, GSM_Ringtone *ringtone) | |||
476 | } else if (strstr(FileName,".wav")) { | 485 | } else if (strstr(FileName,".wav")) { |
477 | savewav(file,ringtone); | 486 | savewav(file,ringtone); |
478 | } else { | 487 | } else { |
479 | saverttl(file, ringtone); | 488 | saverttl(file, ringtone); |
480 | } | 489 | } |
481 | break; | 490 | break; |
482 | case RING_NOKIABINARY: | 491 | case RING_NOKIABINARY: |
483 | savebin(file, ringtone); | 492 | savebin(file, ringtone); |
484 | break; | 493 | break; |
485 | case RING_MIDI: | 494 | case RING_MIDI: |
486 | savepuremidi(file, ringtone); | 495 | savepuremidi(file, ringtone); |
487 | break; | 496 | break; |
497 | case RING_MMF: | ||
498 | savemmf(file, ringtone); | ||
499 | break; | ||
488 | } | 500 | } |
489 | 501 | ||
490 | fclose(file); | 502 | fclose(file); |
491 | 503 | ||
492 | return ERR_NONE; | 504 | return ERR_NONE; |
493 | } | 505 | } |
494 | 506 | ||
495 | static GSM_Error loadrttl(FILE *file, GSM_Ringtone *ringtone) | 507 | static GSM_Error loadrttl(FILE *file, GSM_Ringtone *ringtone) |
496 | { | 508 | { |
497 | GSM_RingNoteScale DefNoteScale= Scale_880; | 509 | GSM_RingNoteScale DefNoteScale= Scale_880; |
498 | GSM_RingNoteDuration DefNoteDuration= Duration_1_4; | 510 | GSM_RingNoteDuration DefNoteDuration= Duration_1_4; |
499 | GSM_RingNoteStyle DefNoteStyle= NaturalStyle; | 511 | GSM_RingNoteStyle DefNoteStyle= NaturalStyle; |
@@ -760,24 +772,44 @@ static GSM_Error loadbin(FILE *file, GSM_Ringtone *ringtone) | |||
760 | static GSM_Error loadpuremidi(FILE *file, GSM_Ringtone *ringtone) | 772 | static GSM_Error loadpuremidi(FILE *file, GSM_Ringtone *ringtone) |
761 | { | 773 | { |
762 | unsigned char buffer[30000]; | 774 | unsigned char buffer[30000]; |
763 | 775 | ||
764 | dbgprintf("loading midi\n"); | 776 | dbgprintf("loading midi\n"); |
765 | EncodeUnicode(ringtone->Name,"MIDI",4); | 777 | EncodeUnicode(ringtone->Name,"MIDI",4); |
766 | ringtone->NokiaBinary.Length=fread(buffer, 1, 30000, file); | 778 | ringtone->NokiaBinary.Length=fread(buffer, 1, 30000, file); |
767 | memcpy(ringtone->NokiaBinary.Frame,buffer,ringtone->NokiaBinary.Length); | 779 | memcpy(ringtone->NokiaBinary.Frame,buffer,ringtone->NokiaBinary.Length); |
768 | dbgprintf("Length %i name \"%s\"\n",ringtone->NokiaBinary.Length,DecodeUnicodeString(ringtone->Name)); | 780 | dbgprintf("Length %i name \"%s\"\n",ringtone->NokiaBinary.Length,DecodeUnicodeString(ringtone->Name)); |
769 | return ERR_NONE; | 781 | return ERR_NONE; |
770 | } | 782 | } |
771 | 783 | ||
784 | static GSM_Error loadmmf(FILE *file, GSM_Ringtone *ringtone) | ||
785 | { | ||
786 | struct stat st; | ||
787 | char *buffer; | ||
788 | int length; | ||
789 | |||
790 | dbgprintf("loading smaf file\n"); | ||
791 | fstat(fileno(file), &st); | ||
792 | ringtone->BinaryTone.Length = length = st.st_size; | ||
793 | ringtone->BinaryTone.Buffer = buffer = malloc(length); | ||
794 | if (buffer == NULL) | ||
795 | return ERR_MOREMEMORY; | ||
796 | fread(buffer, 1, length, file); | ||
797 | |||
798 | dbgprintf("Length %i name \"%s\"\n", length, | ||
799 | DecodeUnicodeString(ringtone->Name)); | ||
800 | |||
801 | return ERR_NONE; | ||
802 | } | ||
803 | |||
772 | static GSM_Error loadre(FILE *file, GSM_Ringtone *ringtone) | 804 | static GSM_Error loadre(FILE *file, GSM_Ringtone *ringtone) |
773 | { | 805 | { |
774 | unsigned char buffer[2000]; | 806 | unsigned char buffer[2000]; |
775 | 807 | ||
776 | ringtone->NokiaBinary.Length=fread(buffer, 1, 500, file); | 808 | ringtone->NokiaBinary.Length=fread(buffer, 1, 500, file); |
777 | 809 | ||
778 | if (buffer[18]==0x00 && buffer[21]!=0x02) { | 810 | if (buffer[18]==0x00 && buffer[21]!=0x02) { |
779 | /* DCT3, Unicode subformat, 62xx & 7110 */ | 811 | /* DCT3, Unicode subformat, 62xx & 7110 */ |
780 | CopyUnicodeString(ringtone->Name,buffer+18); | 812 | CopyUnicodeString(ringtone->Name,buffer+18); |
781 | ringtone->NokiaBinary.Length = ringtone->NokiaBinary.Length - (21+UnicodeLength(ringtone->Name)*2); | 813 | ringtone->NokiaBinary.Length = ringtone->NokiaBinary.Length - (21+UnicodeLength(ringtone->Name)*2); |
782 | memcpy(ringtone->NokiaBinary.Frame,buffer+21+UnicodeLength(ringtone->Name)*2,ringtone->NokiaBinary.Length); | 814 | memcpy(ringtone->NokiaBinary.Frame,buffer+21+UnicodeLength(ringtone->Name)*2,ringtone->NokiaBinary.Length); |
783 | } else { | 815 | } else { |
@@ -807,24 +839,28 @@ GSM_Error GSM_ReadRingtoneFile(char *FileName, GSM_Ringtone *ringtone) | |||
807 | if (buffer[0]==0x00 && buffer[1]==0x00 && | 839 | if (buffer[0]==0x00 && buffer[1]==0x00 && |
808 | buffer[2]==0x0C && buffer[3]==0x01) { | 840 | buffer[2]==0x0C && buffer[3]==0x01) { |
809 | ringtone->Format = RING_NOKIABINARY; | 841 | ringtone->Format = RING_NOKIABINARY; |
810 | } | 842 | } |
811 | if (buffer[0]==0x00 && buffer[1]==0x00 && | 843 | if (buffer[0]==0x00 && buffer[1]==0x00 && |
812 | buffer[2]==0x00) { | 844 | buffer[2]==0x00) { |
813 | ringtone->Format = RING_NOKIABINARY; | 845 | ringtone->Format = RING_NOKIABINARY; |
814 | } | 846 | } |
815 | if (buffer[0]==0x4D && buffer[1]==0x54 && | 847 | if (buffer[0]==0x4D && buffer[1]==0x54 && |
816 | buffer[2]==0x68 && buffer[3]==0x64) { | 848 | buffer[2]==0x68 && buffer[3]==0x64) { |
817 | ringtone->Format = RING_MIDI; | 849 | ringtone->Format = RING_MIDI; |
818 | } | 850 | } |
851 | if (buffer[0]==0x4D && buffer[1]==0x4D && | ||
852 | buffer[2]==0x4D && buffer[3]==0x44) { | ||
853 | ringtone->Format = RING_MMF; | ||
854 | } | ||
819 | } | 855 | } |
820 | rewind(file); | 856 | rewind(file); |
821 | switch (ringtone->Format) { | 857 | switch (ringtone->Format) { |
822 | case RING_NOTETONE: | 858 | case RING_NOTETONE: |
823 | if (buffer[0]==0x02 && buffer[1]==0x4A) { | 859 | if (buffer[0]==0x02 && buffer[1]==0x4A) { |
824 | error=loadott(file,ringtone); | 860 | error=loadott(file,ringtone); |
825 | } else if (buffer[0]==0xC7 && buffer[1]==0x45) { | 861 | } else if (buffer[0]==0xC7 && buffer[1]==0x45) { |
826 | error=loadcommunicator(file,ringtone); | 862 | error=loadcommunicator(file,ringtone); |
827 | } else { | 863 | } else { |
828 | error=loadrttl(file,ringtone); | 864 | error=loadrttl(file,ringtone); |
829 | } | 865 | } |
830 | ringtone->NoteTone.AllNotesScale=false; | 866 | ringtone->NoteTone.AllNotesScale=false; |
@@ -833,24 +869,29 @@ GSM_Error GSM_ReadRingtoneFile(char *FileName, GSM_Ringtone *ringtone) | |||
833 | if (buffer[0]==0x00 && buffer[1]==0x00 && | 869 | if (buffer[0]==0x00 && buffer[1]==0x00 && |
834 | buffer[2]==0x0C && buffer[3]==0x01) { | 870 | buffer[2]==0x0C && buffer[3]==0x01) { |
835 | error=loadbin(file,ringtone); | 871 | error=loadbin(file,ringtone); |
836 | } | 872 | } |
837 | if (buffer[0]==0x00 && buffer[1]==0x00 && | 873 | if (buffer[0]==0x00 && buffer[1]==0x00 && |
838 | buffer[2]==0x00) { | 874 | buffer[2]==0x00) { |
839 | error=loadre(file,ringtone); | 875 | error=loadre(file,ringtone); |
840 | } | 876 | } |
841 | break; | 877 | break; |
842 | case RING_MIDI: | 878 | case RING_MIDI: |
843 | EncodeUnicode(ringtone->Name,FileName,strlen(FileName)); | 879 | EncodeUnicode(ringtone->Name,FileName,strlen(FileName)); |
844 | error = loadpuremidi(file,ringtone); | 880 | error = loadpuremidi(file,ringtone); |
881 | break; | ||
882 | case RING_MMF: | ||
883 | EncodeUnicode(ringtone->Name,FileName,strlen(FileName)); | ||
884 | error = loadmmf(file,ringtone); | ||
885 | break; | ||
845 | } | 886 | } |
846 | fclose(file); | 887 | fclose(file); |
847 | return(error); | 888 | return(error); |
848 | } | 889 | } |
849 | 890 | ||
850 | /* -------------------------- required with Nokia & RTTL ------------------- */ | 891 | /* -------------------------- required with Nokia & RTTL ------------------- */ |
851 | 892 | ||
852 | /* Beats per Minute like written in Smart Messaging */ | 893 | /* Beats per Minute like written in Smart Messaging */ |
853 | static int SM_BeatsPerMinute[] = { | 894 | static int SM_BeatsPerMinute[] = { |
854 | 25, 28, 31, 35, 40, 45, 50, 56, 63,70, | 895 | 25, 28, 31, 35, 40, 45, 50, 56, 63,70, |
855 | 80, 90, 100, 112, 125, 140, 160, 180, 200,225, | 896 | 80, 90, 100, 112, 125, 140, 160, 180, 200,225, |
856 | 250, 285, 320, 355, 400, 450, 500, 565, 635,715, | 897 | 250, 285, 320, 355, 400, 450, 500, 565, 635,715, |