Gammu internals  1.38.0
gsmring.h File Reference
#include <gammu-ringtone.h>
Include dependency graph for gsmring.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define SM_CommandEnd_CommandEnd   0x00
 
#define SM_Command_RingingToneProgramming   (0x25 << 1)
 
#define SM_Command_Sound   (0x1d << 1)
 
#define SM_Song_BasicSongType   (0x01 << 5)
 
#define SM_PatternID_A_part   (0x00 << 6)
 
#define SM_InstructionID_PatternHeaderId   (0x00 << 5)
 
#define SM_InstructionID_NoteInstructionId   (0x01 << 5)
 
#define SM_InstructionID_ScaleInstructionId   (0x02 << 5)
 
#define SM_InstructionID_StyleInstructionId   (0x03 << 5)
 
#define SM_InstructionID_TempoInstructionId   (0x04 << 5)
 
#define SM_InstructionID_VolumeInstructionId   (0x05 << 5)
 

Enumerations

enum  GSM_RingtoneVersion { GSM_Ring_NoHeader = 1, GSM_Ring_PartialHeader, GSM_Ring_IMelody10, GSM_Ring_IMelody12 }
 

Functions

unsigned char GSM_EncodeNokiaRTTLRingtone (GSM_Ringtone *ringtone, unsigned char *package, size_t *maxlength)
 
unsigned char GSM_EncodeEMSSound (GSM_Ringtone *ringtone, unsigned char *package, size_t *maxlength, GSM_RingtoneVersion version, gboolean start)
 
GSM_Error GSM_DecodeNokiaRTTLRingtone (GSM_Ringtone *ringtone, unsigned char *package, size_t maxlength)
 
int GSM_RingNoteGetFrequency (GSM_RingNote Note)
 
int GSM_RingNoteGetFullDuration (GSM_RingNote Note)
 

Macro Definition Documentation

§ SM_Command_RingingToneProgramming

#define SM_Command_RingingToneProgramming   (0x25 << 1)

Definition at line 12 of file gsmring.h.

Referenced by GSM_DecodeNokiaRTTLRingtone(), and GSM_EncodeNokiaRTTLRingtone().

§ SM_Command_Sound

#define SM_Command_Sound   (0x1d << 1)

Definition at line 13 of file gsmring.h.

Referenced by GSM_DecodeNokiaRTTLRingtone(), and GSM_EncodeNokiaRTTLRingtone().

§ SM_CommandEnd_CommandEnd

#define SM_CommandEnd_CommandEnd   0x00

Definition at line 9 of file gsmring.h.

Referenced by GSM_EncodeNokiaRTTLRingtone().

§ SM_InstructionID_NoteInstructionId

#define SM_InstructionID_NoteInstructionId   (0x01 << 5)

Definition at line 23 of file gsmring.h.

Referenced by GSM_DecodeNokiaRTTLRingtone(), and GSM_EncodeNokiaRTTLRingtone().

§ SM_InstructionID_PatternHeaderId

#define SM_InstructionID_PatternHeaderId   (0x00 << 5)

Definition at line 22 of file gsmring.h.

Referenced by GSM_DecodeNokiaRTTLRingtone(), and GSM_EncodeNokiaRTTLRingtone().

§ SM_InstructionID_ScaleInstructionId

#define SM_InstructionID_ScaleInstructionId   (0x02 << 5)

Definition at line 24 of file gsmring.h.

Referenced by GSM_DecodeNokiaRTTLRingtone(), and GSM_EncodeNokiaRTTLRingtone().

§ SM_InstructionID_StyleInstructionId

#define SM_InstructionID_StyleInstructionId   (0x03 << 5)

Definition at line 25 of file gsmring.h.

Referenced by GSM_DecodeNokiaRTTLRingtone(), and GSM_EncodeNokiaRTTLRingtone().

§ SM_InstructionID_TempoInstructionId

#define SM_InstructionID_TempoInstructionId   (0x04 << 5)

Definition at line 26 of file gsmring.h.

Referenced by GSM_DecodeNokiaRTTLRingtone(), and GSM_EncodeNokiaRTTLRingtone().

§ SM_InstructionID_VolumeInstructionId

#define SM_InstructionID_VolumeInstructionId   (0x05 << 5)

Definition at line 27 of file gsmring.h.

Referenced by GSM_DecodeNokiaRTTLRingtone().

§ SM_PatternID_A_part

#define SM_PatternID_A_part   (0x00 << 6)

Definition at line 19 of file gsmring.h.

Referenced by GSM_EncodeNokiaRTTLRingtone().

§ SM_Song_BasicSongType

#define SM_Song_BasicSongType   (0x01 << 5)

Definition at line 16 of file gsmring.h.

Referenced by GSM_DecodeNokiaRTTLRingtone(), and GSM_EncodeNokiaRTTLRingtone().

Enumeration Type Documentation

§ GSM_RingtoneVersion

Enumerator
GSM_Ring_NoHeader 

No header and footer.

GSM_Ring_PartialHeader 

Partial header and footer.

GSM_Ring_IMelody10 

IMelody 1.0.

GSM_Ring_IMelody12 

IMelody 1.2.

Definition at line 31 of file gsmring.h.

Function Documentation

§ GSM_DecodeNokiaRTTLRingtone()

GSM_Error GSM_DecodeNokiaRTTLRingtone ( GSM_Ringtone ringtone,
unsigned char *  package,
size_t  maxlength 
)

Definition at line 1128 of file gsmring.c.

References BufferAlignNumber(), GSM_NoteRingtone::Commands, CopyUnicodeString(), dbgprintf, DecodeUnicodeSpecialNOKIAChars(), GSM_RingNote::Duration, Duration_1_32, Duration_Full, GSM_RingNote::DurationSpec, EncodeUnicode(), ERR_NONE, ERR_NOTSUPPORTED, GSM_Ringtone::Format, GetBuffer(), GetBufferInt(), GSM_MAX_RINGTONE_NOTES, Length_2_3, GSM_Ringtone::Name, NaturalStyle, NoSpecialDuration, GSM_RingNote::Note, GSM_RingCommand::Note, Note_C, Note_H, Note_Pause, GSM_Ringtone::NoteTone, GSM_NoteRingtone::NrCommands, RING_Note, RING_NOTETONE, GSM_RingNote::Scale, Scale_880, SM_BeatsPerMinute, SM_Command_RingingToneProgramming, SM_Command_Sound, SM_InstructionID_NoteInstructionId, SM_InstructionID_PatternHeaderId, SM_InstructionID_ScaleInstructionId, SM_InstructionID_StyleInstructionId, SM_InstructionID_TempoInstructionId, SM_InstructionID_VolumeInstructionId, SM_Song_BasicSongType, StaccatoStyle, GSM_RingNote::Style, GSM_RingNote::Tempo, GSM_RingCommand::Type, and UnicodeLength().

Referenced by GSM_DecodeMultiPartSMS(), loadcommunicator(), and loadott().

1129 {
1130  size_t StartBit=0;
1131  int l, q, i, spec, HowMany;
1132  char Buffer[100];
1133  GSM_RingNote *Note;
1134 
1135  /* Default ringtone parameters */
1136  GSM_RingNoteScale DefScale = Scale_880;
1137  GSM_RingNoteStyle DefStyle = NaturalStyle;
1138  int DefTempo = 63;
1139 
1140  ringtone->Format = RING_NOTETONE;
1141  ringtone->NoteTone.NrCommands = 0;
1142 
1143  GetBufferInt(package,&StartBit,&l,8);
1144  if (l != 0x02) {
1145  dbgprintf(NULL, "Not header\n");
1146  return ERR_NOTSUPPORTED;
1147  }
1148 
1149  GetBufferInt(package,&StartBit,&l,7);
1151  dbgprintf(NULL, "Not RingingToneProgramming\n");
1152  return ERR_NOTSUPPORTED;
1153  }
1154 
1155  /* According to specification we need have next part octet-aligned */
1156  BufferAlignNumber(&StartBit);
1157 
1158  GetBufferInt(package,&StartBit,&l,7);
1159  if (l != SM_Command_Sound) {
1160  dbgprintf(NULL, "Not Sound\n");
1161  return ERR_NOTSUPPORTED;
1162  }
1163 
1164  GetBufferInt(package,&StartBit,&l,3);
1165  if (l != SM_Song_BasicSongType) {
1166  dbgprintf(NULL, "Not BasicSongType\n");
1167  return ERR_NOTSUPPORTED;
1168  }
1169 
1170  /* Getting length of the tune name */
1171  GetBufferInt(package,&StartBit,&l,4);
1172  l=l>>4;
1173 
1174  /* Unpacking the name of the tune. */
1175  GetBuffer(package, &StartBit, Buffer, 8*l);
1176  Buffer[l]=0;
1177  EncodeUnicode(ringtone->Name,Buffer,strlen(Buffer));
1178  DecodeUnicodeSpecialNOKIAChars(Buffer, ringtone->Name, UnicodeLength(ringtone->Name));
1179  CopyUnicodeString(ringtone->Name,Buffer);
1180 
1181  GetBufferInt(package,&StartBit,&l,8);
1182  dbgprintf(NULL, "Number of song patterns: %i\n",l);
1183  /* we support only one song pattern */
1184  if (l!=1) return ERR_NOTSUPPORTED;
1185 
1186  GetBufferInt(package,&StartBit,&l,3);
1188  dbgprintf(NULL, "Not PatternHeaderId\n");
1189  return ERR_NOTSUPPORTED;
1190  }
1191 
1192  /* Pattern ID - we ignore it */
1193  StartBit+=2;
1194 
1195  GetBufferInt(package,&StartBit,&l,4);
1196  l=l>>4;
1197  dbgprintf(NULL, "Loop value: %i\n",l);
1198 
1199  HowMany=0;
1200  GetBufferInt(package, &StartBit, &HowMany, 8);
1201 
1202  for (i=0;i<HowMany;i++) {
1203  GetBufferInt(package,&StartBit,&q,3);
1204  switch (q) {
1206  StartBit+=4;
1207  break;
1209  GetBufferInt(package,&StartBit,&l,2);
1210  if (l>=NaturalStyle && l<=StaccatoStyle) DefStyle = l;
1211  break;
1213  GetBufferInt(package,&StartBit,&l,5);
1214  DefTempo=SM_BeatsPerMinute[l>>3];
1215  break;
1217  GetBufferInt(package,&StartBit,&l,2);
1218  DefScale=(l>>6)+4;
1219  break;
1221  Note = &ringtone->NoteTone.Commands[ringtone->NoteTone.NrCommands].Note;
1222  ringtone->NoteTone.Commands[ringtone->NoteTone.NrCommands].Type = RING_Note;
1223 
1224  GetBufferInt(package,&StartBit,&l,4);
1225  Note->Note=Note_Pause;
1226  if (l >= Note_C && l <= Note_H) Note->Note = l;
1227 
1228  GetBufferInt(package,&StartBit,&l,3);
1229  if (l >= Duration_Full && l <= Duration_1_32) Note->Duration = l;
1230 
1231  GetBufferInt(package,&StartBit,&spec,2);
1232  if (spec >= NoSpecialDuration && spec <= Length_2_3) {
1233  Note->DurationSpec = spec;
1234  }
1235 
1236  Note->Scale = DefScale;
1237  Note->Style = DefStyle;
1238  Note->Tempo = DefTempo;
1239  if (ringtone->NoteTone.NrCommands==GSM_MAX_RINGTONE_NOTES) break;
1240  ringtone->NoteTone.NrCommands++;
1241  break;
1242  default:
1243  dbgprintf(NULL, "Unsupported block %i %i\n",q,i);
1244  return ERR_NOTSUPPORTED;
1245  }
1246  }
1247  return ERR_NONE;
1248 }
GSM_RingCommand Commands[GSM_MAX_RINGTONE_NOTES]
unsigned char Name[(GSM_MAX_RINGTONE_NAME_LENGTH+1) *2]
#define SM_InstructionID_StyleInstructionId
Definition: gsmring.h:25
GSM_RingtoneFormat Format
#define SM_InstructionID_TempoInstructionId
Definition: gsmring.h:26
void CopyUnicodeString(unsigned char *Dest, const unsigned char *Source)
Definition: coding.c:1192
GSM_RingNoteDuration Duration
GSM_RingNoteNote Note
void GetBufferInt(unsigned char *Source, size_t *CurrentBit, int *integer, size_t BitsToProcess)
Definition: coding.c:1329
GSM_RingNoteScale Scale
GSM_RingCommandType Type
#define SM_InstructionID_NoteInstructionId
Definition: gsmring.h:23
GSM_RingNoteScale
size_t UnicodeLength(const unsigned char *str)
Definition: coding.c:186
#define SM_InstructionID_ScaleInstructionId
Definition: gsmring.h:24
GSM_NoteRingtone NoteTone
void BufferAlignNumber(size_t *CurrentBit)
Definition: coding.c:1275
static int SM_BeatsPerMinute[]
Definition: gsmring.c:972
#define SM_Command_RingingToneProgramming
Definition: gsmring.h:12
#define GSM_MAX_RINGTONE_NOTES
Definition: gammu-limits.h:225
void GetBuffer(unsigned char *Source, size_t *CurrentBit, unsigned char *Destination, size_t BitsToProcess)
Definition: coding.c:1311
void EncodeUnicode(unsigned char *dest, const char *src, size_t len)
Definition: coding.c:301
GSM_RingNoteStyle Style
GSM_RingNoteDurationSpec DurationSpec
GSM_RingNoteStyle
void DecodeUnicodeSpecialNOKIAChars(unsigned char *dest, const unsigned char *src, size_t len)
Definition: coding.c:1401
#define dbgprintf
Definition: debug.h:72
#define SM_InstructionID_VolumeInstructionId
Definition: gsmring.h:27
GSM_RingNote Note
#define SM_InstructionID_PatternHeaderId
Definition: gsmring.h:22
#define SM_Command_Sound
Definition: gsmring.h:13
#define SM_Song_BasicSongType
Definition: gsmring.h:16

§ GSM_EncodeEMSSound()

unsigned char GSM_EncodeEMSSound ( GSM_Ringtone ringtone,
unsigned char *  package,
size_t *  maxlength,
GSM_RingtoneVersion  version,
gboolean  start 
)

Definition at line 1565 of file gsmring.c.

References GSM_NoteRingtone::Commands, ContinuousStyle, dbgprintf, DecodeUnicodeString(), DottedNote, DoubleDottedNote, GSM_RingNote::Duration, Duration_1_16, Duration_1_2, Duration_1_32, Duration_1_4, Duration_1_8, Duration_Full, GSM_RingNote::DurationSpec, FALSE, GSM_Ring_IMelody10, GSM_Ring_IMelody12, GSM_Ring_NoHeader, INVALIDStyle, Length_2_3, GSM_Ringtone::Name, NaturalStyle, GSM_RingNote::Note, GSM_RingCommand::Note, Note_A, Note_Ais, Note_C, Note_Cis, Note_D, Note_Dis, Note_E, Note_F, Note_Fis, Note_G, Note_Gis, Note_H, Note_INVALID, Note_Pause, GSM_Ringtone::NoteTone, GSM_NoteRingtone::NrCommands, RING_DisableLED, RING_DisableLight, RING_DisableVibra, RING_EnableLED, RING_EnableLight, RING_EnableVibra, RING_Note, GSM_RingNote::Scale, Scale_880, StaccatoStyle, GSM_RingNote::Style, GSM_RingNote::Tempo, TRUE, and GSM_RingCommand::Type.

Referenced by GSM_EncodeEMSMultiPartSMS(), and GSM_SaveRingtoneIMelody().

1566 {
1567  int i, NrNotes = 0, Len, Max = *maxlength;
1568 
1569  GSM_RingNote *Note;
1570 
1571  GSM_RingNoteScale DefNoteScale;
1572  GSM_RingNoteStyle DefNoteStyle=0;
1573  int DefNoteTempo=0;
1574 
1575  gboolean started = FALSE, end;
1576 
1577  *maxlength = 0;
1578 
1579  if (start) {
1580  if (version != GSM_Ring_NoHeader)
1581  *maxlength+=sprintf(package,"BEGIN:IMELODY%c%c",13,10);
1582  if (version == GSM_Ring_IMelody10)
1583  *maxlength+=sprintf(package+(*maxlength),"VERSION:1.0%c%c",13,10);
1584  if (version == GSM_Ring_IMelody12)
1585  *maxlength+=sprintf(package+(*maxlength),"VERSION:1.2%c%c",13,10);
1586  if (version == GSM_Ring_IMelody12 || version == GSM_Ring_IMelody10)
1587  *maxlength+=sprintf(package+(*maxlength),"FORMAT:CLASS1.0%c%c",13,10);
1588  if (version == GSM_Ring_IMelody12)
1589  *maxlength+=sprintf(package+(*maxlength),"NAME:%s%c%c",DecodeUnicodeString(ringtone->Name),13,10);
1590  }
1591 
1592  DefNoteScale = Scale_880; /* by iMelody definition */
1593 
1594  for (i=0;i<ringtone->NoteTone.NrCommands;i++) {
1595  Len = *maxlength;
1596  if (ringtone->NoteTone.Commands[i].Type != RING_Note) continue;
1597 
1598  Note = &ringtone->NoteTone.Commands[i].Note;
1599  if (Note->Note == Note_Pause) continue;
1600 
1601  if (version == GSM_Ring_IMelody12 && start) {
1602  /* Save the default tempo */
1603  DefNoteTempo = Note->Tempo;
1604  Len+=sprintf(package+Len,"BEAT:%i%c%c",DefNoteTempo,13,10);
1605  dbgprintf(NULL, "DefNoteTempo=%d\n",DefNoteTempo);
1606 
1607  /* Save default style */
1608  DefNoteStyle = Note->Style;
1609  switch (DefNoteStyle) {
1610  case INVALIDStyle: break;
1611  case NaturalStyle :Len+=sprintf(package+Len,"STYLE:S0%c%c",13,10); break;
1612  case ContinuousStyle:Len+=sprintf(package+Len,"STYLE:S1%c%c",13,10); break;
1613  case StaccatoStyle :Len+=sprintf(package+Len,"STYLE:S2%c%c",13,10); break;
1614  }
1615  }
1616  Len+=sprintf(package+Len,"MELODY:");
1617  if (version != GSM_Ring_NoHeader) {
1618  /* 15 = Len of END:IMELODY... */
1619  if ((Len+15) > Max) { break; }
1620  } else {
1621  if (Len > Max) { break; }
1622  }
1623  *maxlength = Len;
1624  break;
1625  }
1626 
1627  for (i=0;i<ringtone->NoteTone.NrCommands;i++) {
1628  end = FALSE;
1629  Len = *maxlength;
1630  switch (ringtone->NoteTone.Commands[i].Type) {
1631  case RING_Note:
1632  Note = &ringtone->NoteTone.Commands[i].Note;
1633  if (!started && Note->Note != Note_Pause) started = TRUE;
1634  if (!started) break;
1635  if (Note->Note!=Note_Pause && Note->Scale != DefNoteScale) {
1636  Len+=sprintf(package+Len,"*%i",Note->Scale-1);
1637  }
1638  switch (Note->Note) {
1639  case Note_C :Len+=sprintf(package+Len,"c"); break;
1640  case Note_Cis :Len+=sprintf(package+Len,"#c");break;
1641  case Note_D :Len+=sprintf(package+Len,"d"); break;
1642  case Note_Dis :Len+=sprintf(package+Len,"#d");break;
1643  case Note_E :Len+=sprintf(package+Len,"e"); break;
1644  case Note_F :Len+=sprintf(package+Len,"f"); break;
1645  case Note_Fis :Len+=sprintf(package+Len,"#f");break;
1646  case Note_G :Len+=sprintf(package+Len,"g"); break;
1647  case Note_Gis :Len+=sprintf(package+Len,"#g");break;
1648  case Note_A :Len+=sprintf(package+Len,"a"); break;
1649  case Note_Ais :Len+=sprintf(package+Len,"#a");break;
1650  case Note_H :Len+=sprintf(package+Len,"b"); break;
1651  case Note_Pause :Len+=sprintf(package+Len,"r"); break;
1652  case Note_INVALID: break;
1653  }
1654  switch (Note->Duration) {
1655  case Duration_Full : package[Len++]='0'; break;
1656  case Duration_1_2 : package[Len++]='1'; break;
1657  case Duration_1_4 : package[Len++]='2'; break;
1658  case Duration_1_8 : package[Len++]='3'; break;
1659  case Duration_1_16 : package[Len++]='4'; break;
1660  case Duration_1_32 : package[Len++]='5'; break;
1661  default : break;
1662  }
1663  switch (Note->DurationSpec) {
1664  case DottedNote : package[Len++] = '.'; break;
1665  case DoubleDottedNote : package[Len++] = ':'; break;
1666  case Length_2_3 : package[Len++] = ';'; break;
1667  default : break;
1668  }
1669  if (version != 0) {
1670  /* 15 = Len of END:IMELODY... */
1671  if ((Len+15) > Max) { end = TRUE; break; }
1672  } else {
1673  if (Len > Max) { end = TRUE; break; }
1674  }
1675  *maxlength = Len;
1676  break;
1677  case RING_DisableLED:
1678  if ((Len + 6) > Max) { end = TRUE; break; }
1679  (*maxlength)+=sprintf(package+Len,"ledoff");
1680  break;
1681  case RING_EnableLED:
1682  if ((Len + 5) > Max) { end = TRUE; break; }
1683  (*maxlength)+=sprintf(package+Len,"ledon");
1684  break;
1685  case RING_DisableVibra:
1686  if ((Len + 7) > Max) { end = TRUE; break; }
1687  (*maxlength)+=sprintf(package+Len,"vibeoff");
1688  break;
1689  case RING_EnableVibra:
1690  if ((Len + 6) > Max) { end = TRUE; break; }
1691  (*maxlength)+=sprintf(package+Len,"vibeon");
1692  break;
1693  case RING_DisableLight:
1694  if ((Len + 7) > Max) { end = TRUE; break; }
1695  (*maxlength)+=sprintf(package+Len,"backoff");
1696  break;
1697  case RING_EnableLight:
1698  if ((Len + 6) > Max) { end = TRUE; break; }
1699  (*maxlength)+=sprintf(package+Len,"backon");
1700  break;
1701  default:
1702  break;
1703  }
1704  if (end) break;
1705  NrNotes ++;
1706  }
1707 
1708  if (version != 0) *maxlength+=sprintf(package+(*maxlength),"%c%cEND:IMELODY%c%c",13,10,13,10);
1709 
1710  return NrNotes;
1711 }
GSM_RingCommand Commands[GSM_MAX_RINGTONE_NOTES]
unsigned char Name[(GSM_MAX_RINGTONE_NAME_LENGTH+1) *2]
char * DecodeUnicodeString(const unsigned char *src)
Definition: coding.c:245
GSM_RingNoteDuration Duration
GSM_RingNoteNote Note
GSM_RingNoteScale Scale
GSM_RingCommandType Type
GSM_RingNoteScale
GSM_NoteRingtone NoteTone
int gboolean
Definition: gammu-types.h:23
#define FALSE
Definition: gammu-types.h:25
GSM_RingNoteStyle Style
GSM_RingNoteDurationSpec DurationSpec
GSM_RingNoteStyle
#define dbgprintf
Definition: debug.h:72
#define TRUE
Definition: gammu-types.h:28
GSM_RingNote Note

§ GSM_EncodeNokiaRTTLRingtone()

unsigned char GSM_EncodeNokiaRTTLRingtone ( GSM_Ringtone ringtone,
unsigned char *  package,
size_t *  maxlength 
)

Definition at line 992 of file gsmring.c.

References AddBuffer(), AddBufferByte(), GSM_NoteRingtone::AllNotesScale, BufferAlign(), BufferAlignNumber(), GSM_NoteRingtone::Commands, DecodeUnicodeString(), GSM_RingNote::Duration, GSM_RingNote::DurationSpec, EncodeUnicodeSpecialNOKIAChars(), FALSE, GSM_RTTLGetTempo(), GSM_Ringtone::Name, GSM_RingNote::Note, GSM_RingCommand::Note, Note_Pause, GSM_Ringtone::NoteTone, GSM_NoteRingtone::NrCommands, RING_Note, GSM_RingNote::Scale, SM_Command_RingingToneProgramming, SM_Command_Sound, SM_CommandEnd_CommandEnd, SM_InstructionID_NoteInstructionId, SM_InstructionID_PatternHeaderId, SM_InstructionID_ScaleInstructionId, SM_InstructionID_StyleInstructionId, SM_InstructionID_TempoInstructionId, SM_PatternID_A_part, SM_Song_BasicSongType, GSM_RingNote::Style, GSM_RingNote::Tempo, TRUE, GSM_RingCommand::Type, and UnicodeLength().

Referenced by GSM_EncodeMultiPartSMS(), GSM_EncodeSMS30MultiPartSMS(), and GSM_SaveRingtoneOtt().

993 {
994  unsigned char CommandLength = 0x02;
995  unsigned char Loop = 0x15; /* Infinite */
996 
997  unsigned char Buffer[200];
998  size_t StartBit=0, OldStartBit;
999  int StartBitHowManyCommands;
1000  int HowManyCommands = 0; /* How many instructions packed */
1001  int HowManyNotes = 0;
1002  int i;
1003  size_t j;
1004  gboolean started;
1005  GSM_RingNote *Note;
1006 
1007  GSM_RingNoteScale DefScale = 255;
1008  GSM_RingNoteStyle DefStyle = 255;
1009  int DefTempo = 255;
1010 
1011  AddBufferByte(package, &StartBit, CommandLength, 8);
1012  AddBufferByte(package, &StartBit, SM_Command_RingingToneProgramming, 7);
1013 
1014  /* According to specification we need have next part octet-aligned */
1015  BufferAlign(package, &StartBit);
1016 
1017  AddBufferByte(package, &StartBit, SM_Command_Sound, 7);
1018  AddBufferByte(package, &StartBit, SM_Song_BasicSongType, 3);
1019 
1020  /* Packing the name of the tune. */
1021  EncodeUnicodeSpecialNOKIAChars(Buffer, ringtone->Name, UnicodeLength(ringtone->Name));
1022  AddBufferByte(package, &StartBit, ((unsigned char)(UnicodeLength(Buffer)<<4)), 4);
1023  AddBuffer(package, &StartBit, DecodeUnicodeString(Buffer), 8*UnicodeLength(Buffer));
1024 
1025  /* Packing info about song pattern */
1026  AddBufferByte(package, &StartBit, 0x01, 8); /* one pattern */
1027  AddBufferByte(package, &StartBit, SM_InstructionID_PatternHeaderId, 3);
1028  AddBufferByte(package, &StartBit, SM_PatternID_A_part, 2);
1029  AddBufferByte(package, &StartBit, ((unsigned char)(Loop<<4)), 4);
1030 
1031  /* Later here will be HowManyCommands */
1032  StartBitHowManyCommands=StartBit;
1033  StartBit = StartBit + 8;
1034 
1035  started = FALSE;
1036  for (i=0; i<ringtone->NoteTone.NrCommands; i++) {
1037  if (ringtone->NoteTone.Commands[i].Type != RING_Note) {
1038  HowManyNotes++;
1039  continue;
1040  }
1041  Note = &ringtone->NoteTone.Commands[i].Note;
1042  if (!started) {
1043  /* First note can't be Pause - it makes problems
1044  * for example with PC Composer
1045  */
1046  if (Note->Note != Note_Pause) started = TRUE;
1047  }
1048  if (!started) {
1049  HowManyNotes++;
1050  continue;
1051  }
1052  OldStartBit = StartBit;
1053  /* we don't write Scale & Style info before "Pause" note - it saves place */
1054  if (Note->Note!=Note_Pause) {
1055  if (DefScale != Note->Scale || ringtone->NoteTone.AllNotesScale) {
1056  j = StartBit+5+8;
1057  BufferAlignNumber(&j);
1058  if ((j/8)>(*maxlength)) {
1059  StartBit = OldStartBit;
1060  break;
1061  }
1062  DefScale = Note->Scale;
1063  AddBufferByte(package, &StartBit, SM_InstructionID_ScaleInstructionId, 3);
1064  AddBufferByte(package, &StartBit, ((unsigned char)((DefScale-4)<<6)), 2);
1065  HowManyCommands++;
1066  }
1067  if (DefStyle != Note->Style) {
1068  j = StartBit+5+8;
1069  BufferAlignNumber(&j);
1070  if ((j/8)>(*maxlength)) {
1071  StartBit = OldStartBit;
1072  break;
1073  }
1074  DefStyle = Note->Style;
1075  AddBufferByte(package, &StartBit, SM_InstructionID_StyleInstructionId, 3);
1076  AddBufferByte(package, &StartBit, ((unsigned char)DefStyle), 2);
1077  HowManyCommands++;
1078  }
1079  }
1080  /* Beats per minute/tempo of the tune */
1081  if (DefTempo != GSM_RTTLGetTempo(Note->Tempo)) {
1082  j = StartBit+8+8;
1083  BufferAlignNumber(&j);
1084  if ((j/8)>(*maxlength)) {
1085  StartBit = OldStartBit;
1086  break;
1087  }
1088  DefTempo=GSM_RTTLGetTempo(Note->Tempo);
1089  /* Adding beats per minute (tempo) of the tune */
1090  AddBufferByte(package, &StartBit, SM_InstructionID_TempoInstructionId, 3);
1091  AddBufferByte(package, &StartBit, ((unsigned char)DefTempo), 5);
1092  HowManyCommands++;
1093  }
1094  j = StartBit+12+8;
1095  BufferAlignNumber(&j);
1096  if ((j/8)>(*maxlength)) {
1097  StartBit = OldStartBit;
1098  break;
1099  }
1100  /* Note */
1101  AddBufferByte(package, &StartBit, SM_InstructionID_NoteInstructionId, 3);
1102  AddBufferByte(package, &StartBit, ((unsigned char)Note->Note), 4);
1103  AddBufferByte(package, &StartBit, ((unsigned char)Note->Duration), 3);
1104  AddBufferByte(package, &StartBit, ((unsigned char)Note->DurationSpec), 2);
1105  HowManyCommands++;
1106  /* We are sure, we pack it for SMS or setting to phone, not for OTT file */
1107  if (*maxlength<1000) {
1108  /* Like Pc Composer say - before of phone limitations...*/
1109  if (HowManyNotes==130-1) break;
1110  }
1111  HowManyNotes++;
1112  }
1113 
1114  BufferAlign(package, &StartBit);
1115  AddBufferByte(package, &StartBit, SM_CommandEnd_CommandEnd, 8);
1116 
1117  OldStartBit = StartBit;
1118  StartBit = StartBitHowManyCommands;
1119  /* HowManyCommands */
1120  AddBufferByte(package, &StartBit, ((unsigned char)HowManyCommands), 8);
1121  StartBit = OldStartBit;
1122 
1123  *maxlength=StartBit/8;
1124 
1125  return(i);
1126 }
GSM_RingCommand Commands[GSM_MAX_RINGTONE_NOTES]
unsigned char Name[(GSM_MAX_RINGTONE_NAME_LENGTH+1) *2]
#define SM_InstructionID_StyleInstructionId
Definition: gsmring.h:25
char * DecodeUnicodeString(const unsigned char *src)
Definition: coding.c:245
#define SM_InstructionID_TempoInstructionId
Definition: gsmring.h:26
GSM_RingNoteDuration Duration
void AddBufferByte(unsigned char *Destination, size_t *CurrentBit, unsigned char Source, size_t BitsToProcess)
Definition: coding.c:1303
GSM_RingNoteNote Note
void BufferAlign(unsigned char *Destination, size_t *CurrentBit)
Definition: coding.c:1263
GSM_RingNoteScale Scale
GSM_RingCommandType Type
#define SM_InstructionID_NoteInstructionId
Definition: gsmring.h:23
GSM_RingNoteScale
size_t UnicodeLength(const unsigned char *str)
Definition: coding.c:186
#define SM_InstructionID_ScaleInstructionId
Definition: gsmring.h:24
GSM_NoteRingtone NoteTone
void BufferAlignNumber(size_t *CurrentBit)
Definition: coding.c:1275
int GSM_RTTLGetTempo(int Beats)
Definition: gsmring.c:979
#define SM_CommandEnd_CommandEnd
Definition: gsmring.h:9
#define SM_Command_RingingToneProgramming
Definition: gsmring.h:12
int gboolean
Definition: gammu-types.h:23
#define FALSE
Definition: gammu-types.h:25
GSM_RingNoteStyle Style
GSM_RingNoteDurationSpec DurationSpec
GSM_RingNoteStyle
void AddBuffer(unsigned char *Destination, size_t *CurrentBit, unsigned char *Source, size_t BitsToProcess)
Definition: coding.c:1286
void EncodeUnicodeSpecialNOKIAChars(unsigned char *dest, const unsigned char *src, size_t len)
Definition: coding.c:1367
#define TRUE
Definition: gammu-types.h:28
GSM_RingNote Note
#define SM_InstructionID_PatternHeaderId
Definition: gsmring.h:22
#define SM_Command_Sound
Definition: gsmring.h:13
#define SM_PatternID_A_part
Definition: gsmring.h:19
#define SM_Song_BasicSongType
Definition: gsmring.h:16
gboolean AllNotesScale

§ GSM_RingNoteGetFrequency()

int GSM_RingNoteGetFrequency ( GSM_RingNote  Note)

Definition at line 40 of file gsmring.c.

References GSM_RingNote::Note, Note_A, Note_Ais, Note_C, Note_Cis, Note_D, Note_Dis, Note_E, Note_F, Note_Fis, Note_G, Note_Gis, Note_H, Note_INVALID, Note_Pause, GSM_RingNote::Scale, Scale_1760, Scale_3520, Scale_440, and Scale_880.

Referenced by GSM_SaveRingtoneWav(), and PHONE_RTTLPlayOneNote().

41 {
42  int freq = 0;
43 
44  /* Values according to the software from http://iki.fi/too/sw/xring/
45  * generated with:
46  * perl -e 'print int(4400 * (2 **($_/12)) + .5)/10, "\n" for(3..14)'
47  */
48  switch (Note.Note) {
49  case Note_C : freq = 52330; break;
50  case Note_Cis: freq = 55440; break;
51  case Note_D : freq = 58730; break;
52  case Note_Dis: freq = 62230; break;
53  case Note_E : freq = 65930; break;
54  case Note_F : freq = 69850; break;
55  case Note_Fis: freq = 74000; break;
56  case Note_G : freq = 78400; break;
57  case Note_Gis: freq = 83060; break;
58  case Note_A : freq = 88000; break;
59  case Note_Ais: freq = 93230; break;
60  case Note_H : freq = 98780; break;
61  case Note_Pause: break;
62  case Note_INVALID: break;
63  }
64  if (Note.Note != Note_Pause) {
65  switch (Note.Scale) {
66  case Scale_440 : freq = freq / 2; break;
67  case Scale_880 : break;
68  case Scale_1760: freq = freq * 2; break;
69  case Scale_3520: freq = freq * 4; break;
70  default : break;
71  }
72  }
73  return freq / 100;
74 }
GSM_RingNoteNote Note
GSM_RingNoteScale Scale

§ GSM_RingNoteGetFullDuration()

int GSM_RingNoteGetFullDuration ( GSM_RingNote  Note)

Definition at line 76 of file gsmring.c.

References DottedNote, DoubleDottedNote, GSM_RingNote::Duration, Duration_1_16, Duration_1_2, Duration_1_32, Duration_1_4, Duration_1_8, Duration_Full, Duration_INVALID, GSM_RingNote::DurationSpec, DurationSpec_INVALID, Length_2_3, and NoSpecialDuration.

Referenced by GSM_SaveRingtoneMidi(), GSM_SaveRingtoneWav(), PHONE_RTTLPlayOneNote(), and RTTL2Binary().

77 {
78  int duration = 1;
79 
80  switch (Note.Duration) {
81  case Duration_Full : duration = 128; break;
82  case Duration_1_2 : duration = 64; break;
83  case Duration_1_4 : duration = 32; break;
84  case Duration_1_8 : duration = 16; break;
85  case Duration_1_16 : duration = 8; break;
86  case Duration_1_32 : duration = 4; break;
87  case Duration_INVALID: break;
88  }
89  switch (Note.DurationSpec) {
90  case NoSpecialDuration : break;
91  case DottedNote : duration = duration * 3/2; break;
92  case DoubleDottedNote : duration = duration * 9/4; break;
93  case Length_2_3 : duration = duration * 2/3; break;
94  case DurationSpec_INVALID: break;
95  }
96  return duration;
97 }
GSM_RingNoteDuration Duration
GSM_RingNoteDurationSpec DurationSpec