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

Go to the source code of this file.

Data Structures

struct  GSM_RingNote
 
struct  GSM_RingCommand
 
struct  GSM_NoteRingtone
 
struct  GSM_NokiaBinaryRingtone
 
struct  GSM_BinaryTone
 
struct  GSM_Ringtone
 
struct  GSM_RingtoneInfo
 
struct  GSM_AllRingtonesInfo
 

Enumerations

enum  GSM_RingNoteStyle { NaturalStyle = 0x00 << 6, ContinuousStyle = 0x01 << 6, StaccatoStyle = 0x02 << 6, INVALIDStyle }
 
enum  GSM_RingNoteNote {
  Note_Pause = 0x00 << 4, Note_C = 0x01 << 4, Note_Cis = 0x02 << 4, Note_D = 0x03 << 4,
  Note_Dis = 0x04 << 4, Note_E = 0x05 << 4, Note_F = 0x06 << 4, Note_Fis = 0x07 << 4,
  Note_G = 0x08 << 4, Note_Gis = 0x09 << 4, Note_A = 0x0a << 4, Note_Ais = 0x0b << 4,
  Note_H = 0x0c << 4, Note_INVALID
}
 
enum  GSM_RingNoteDuration {
  Duration_Full = 0x00 << 5, Duration_1_2 = 0x01 << 5, Duration_1_4 = 0x02 << 5, Duration_1_8 = 0x03 << 5,
  Duration_1_16 = 0x04 << 5, Duration_1_32 = 0x05 << 5, Duration_INVALID
}
 
enum  GSM_RingNoteDurationSpec {
  NoSpecialDuration = 0x00 << 6, DottedNote = 0x01 << 6, DoubleDottedNote = 0x02 << 6, Length_2_3 = 0x03 << 6,
  DurationSpec_INVALID
}
 
enum  GSM_RingNoteScale {
  Scale_55 = 1, Scale_110, Scale_220, Scale_440,
  Scale_880, Scale_1760, Scale_3520, Scale_7040,
  Scale_14080
}
 
enum  GSM_RingCommandType {
  RING_Note = 1, RING_EnableVibra, RING_DisableVibra, RING_EnableLight,
  RING_DisableLight, RING_EnableLED, RING_DisableLED, RING_Repeat
}
 
enum  GSM_RingtoneFormat { RING_NOTETONE = 1, RING_NOKIABINARY, RING_MIDI, RING_MMF }
 

Functions

GSM_Error PHONE_RTTLPlayOneNote (GSM_StateMachine *s, GSM_RingNote note, gboolean first)
 
GSM_Error PHONE_Beep (GSM_StateMachine *s)
 
GSM_Error GSM_GetRingtone (GSM_StateMachine *s, GSM_Ringtone *Ringtone, gboolean PhoneRingtone)
 
GSM_Error GSM_SetRingtone (GSM_StateMachine *s, GSM_Ringtone *Ringtone, int *maxlength)
 
GSM_Error GSM_GetRingtonesInfo (GSM_StateMachine *s, GSM_AllRingtonesInfo *Info)
 
GSM_Error GSM_DeleteUserRingtones (GSM_StateMachine *s)
 
GSM_Error GSM_PlayTone (GSM_StateMachine *s, int Herz, unsigned char Volume, gboolean start)
 
GSM_Error GSM_RingtoneConvert (GSM_Ringtone *dest, GSM_Ringtone *src, GSM_RingtoneFormat Format)
 
GSM_Error GSM_ReadRingtoneFile (char *FileName, GSM_Ringtone *ringtone)
 
GSM_Error GSM_SaveRingtoneFile (char *FileName, GSM_Ringtone *ringtone)
 
GSM_Error GSM_SaveRingtoneOtt (FILE *file, GSM_Ringtone *ringtone)
 
GSM_Error GSM_SaveRingtoneMidi (FILE *file, GSM_Ringtone *ringtone)
 
GSM_Error GSM_SaveRingtoneIMelody (FILE *file, GSM_Ringtone *ringtone)
 
GSM_Error GSM_SaveRingtoneWav (FILE *file, GSM_Ringtone *ringtone)
 
GSM_Error GSM_SaveRingtoneRttl (FILE *file, GSM_Ringtone *ringtone)
 
const unsigned char * GSM_GetRingtoneName (const GSM_AllRingtonesInfo *Info, const int ID)
 
int GSM_RTTLGetTempo (int Beats)
 

Detailed Description

Author
Michal Čihař

Ringtone data and functions.

Definition in file gammu-ringtone.h.

Enumeration Type Documentation

§ GSM_RingCommandType

Enumerator
RING_Note 
RING_EnableVibra 
RING_DisableVibra 
RING_EnableLight 
RING_DisableLight 
RING_EnableLED 
RING_DisableLED 
RING_Repeat 

Definition at line 114 of file gammu-ringtone.h.

§ GSM_RingNoteDuration

Enumerator
Duration_Full 
Duration_1_2 
Duration_1_4 
Duration_1_8 
Duration_1_16 
Duration_1_32 
Duration_INVALID 

Definition at line 61 of file gammu-ringtone.h.

61  {
62  Duration_Full = 0x00 << 5,
63  Duration_1_2 = 0x01 << 5,
64  Duration_1_4 = 0x02 << 5,
65  Duration_1_8 = 0x03 << 5,
66  Duration_1_16 = 0x04 << 5,
67  Duration_1_32 = 0x05 << 5,
68 
GSM_RingNoteDuration

§ GSM_RingNoteDurationSpec

Enumerator
NoSpecialDuration 
DottedNote 
DoubleDottedNote 
Length_2_3 
DurationSpec_INVALID 

Definition at line 72 of file gammu-ringtone.h.

§ GSM_RingNoteNote

Enumerator
Note_Pause 
Note_C 
Note_Cis 
Note_D 
Note_Dis 
Note_E 
Note_F 
Note_Fis 
Note_G 
Note_Gis 
Note_A 
Note_Ais 
Note_H 
Note_INVALID 

Definition at line 43 of file gammu-ringtone.h.

43  {
44  Note_Pause = 0x00 << 4,
45  Note_C = 0x01 << 4,
46  Note_Cis = 0x02 << 4,
47  Note_D = 0x03 << 4,
48  Note_Dis = 0x04 << 4,
49  Note_E = 0x05 << 4,
50  Note_F = 0x06 << 4,
51  Note_Fis = 0x07 << 4,
52  Note_G = 0x08 << 4,
53  Note_Gis = 0x09 << 4,
54  Note_A = 0x0a << 4,
55  Note_Ais = 0x0b << 4,
56  Note_H = 0x0c << 4,
57 
GSM_RingNoteNote

§ GSM_RingNoteScale

Enumerator
Scale_55 

55 Hz for note A

Scale_110 

110 Hz for note A

Scale_220 
Scale_440 

first scale for Nokia

Scale_880 
Scale_1760 
Scale_3520 

last scale for Nokia

Scale_7040 
Scale_14080 

Definition at line 81 of file gammu-ringtone.h.

§ GSM_RingNoteStyle

Enumerator
NaturalStyle 

Natural style (rest between notes)

ContinuousStyle 

Continuous style (no rest between notes)

StaccatoStyle 

Staccato style (shorter notes and longer rest period)

INVALIDStyle 

Definition at line 26 of file gammu-ringtone.h.

26  {
30  NaturalStyle = 0x00 << 6,
34  ContinuousStyle = 0x01 << 6,
38  StaccatoStyle = 0x02 << 6,
39 
GSM_RingNoteStyle

§ GSM_RingtoneFormat

Enumerator
RING_NOTETONE 
RING_NOKIABINARY 
RING_MIDI 
RING_MMF 

Definition at line 149 of file gammu-ringtone.h.

Function Documentation

§ GSM_DeleteUserRingtones()

GSM_Error GSM_DeleteUserRingtones ( GSM_StateMachine s)

Deletes user defined ringtones from phone.

Definition at line 1092 of file api.c.

References CHECK_PHONE_CONNECTION, GSM_Phone_Functions::DeleteUserRingtones, GSM_Phone::Functions, _GSM_StateMachine::Phone, and PRINT_LOG_ERROR.

1093 {
1094  GSM_Error err;
1095 
1097 
1098  err = s->Phone.Functions->DeleteUserRingtones(s);
1099  PRINT_LOG_ERROR(err);
1100  return err;
1101 }
GSM_Error
Definition: gammu-error.h:23
GSM_Phone Phone
Definition: gsmstate.h:1431
#define PRINT_LOG_ERROR(err)
Definition: api.c:28
#define CHECK_PHONE_CONNECTION()
Definition: api.c:38
GSM_Phone_Functions * Functions
Definition: gsmstate.h:1373
GSM_Error(* DeleteUserRingtones)(GSM_StateMachine *s)
Definition: gsmstate.h:1071

§ GSM_GetRingtone()

GSM_Error GSM_GetRingtone ( GSM_StateMachine s,
GSM_Ringtone Ringtone,
gboolean  PhoneRingtone 
)

Gets ringtone from phone.

Definition at line 1053 of file api.c.

References CHECK_PHONE_CONNECTION, GSM_Phone::Functions, GSM_Phone_Functions::GetRingtone, _GSM_StateMachine::Phone, and PRINT_LOG_ERROR.

1054 {
1055  GSM_Error err;
1056 
1058 
1059  err = s->Phone.Functions->GetRingtone(s, Ringtone, PhoneRingtone);
1060  PRINT_LOG_ERROR(err);
1061  return err;
1062 }
GSM_Error
Definition: gammu-error.h:23
GSM_Phone Phone
Definition: gsmstate.h:1431
#define PRINT_LOG_ERROR(err)
Definition: api.c:28
#define CHECK_PHONE_CONNECTION()
Definition: api.c:38
GSM_Error(* GetRingtone)(GSM_StateMachine *s, GSM_Ringtone *Ringtone, gboolean PhoneRingtone)
Definition: gsmstate.h:1059
GSM_Phone_Functions * Functions
Definition: gsmstate.h:1373

§ GSM_GetRingtoneName()

const unsigned char* GSM_GetRingtoneName ( const GSM_AllRingtonesInfo Info,
const int  ID 
)

Returns ringtone name, NULL if not found.

Definition at line 1713 of file gsmring.c.

References GSM_RingtoneInfo::ID, GSM_RingtoneInfo::Name, GSM_AllRingtonesInfo::Number, and GSM_AllRingtonesInfo::Ringtone.

1714 {
1715  int i;
1716 
1717  for (i = 0; i < Info->Number; i++) {
1718  if (Info->Ringtone[i].ID == ID) {
1719  return Info->Ringtone[i].Name;
1720  }
1721  }
1722 
1723  return NULL;
1724 }
GSM_RingtoneInfo * Ringtone
unsigned char Name[30 *2]

§ GSM_GetRingtonesInfo()

GSM_Error GSM_GetRingtonesInfo ( GSM_StateMachine s,
GSM_AllRingtonesInfo Info 
)

Acquires ringtone informaiton.

Definition at line 1079 of file api.c.

References CHECK_PHONE_CONNECTION, GSM_Phone::Functions, GSM_Phone_Functions::GetRingtonesInfo, _GSM_StateMachine::Phone, and PRINT_LOG_ERROR.

1080 {
1081  GSM_Error err;
1082 
1084 
1085  err = s->Phone.Functions->GetRingtonesInfo(s, Info);
1086  PRINT_LOG_ERROR(err);
1087  return err;
1088 }
GSM_Error
Definition: gammu-error.h:23
GSM_Error(* GetRingtonesInfo)(GSM_StateMachine *s, GSM_AllRingtonesInfo *Info)
Definition: gsmstate.h:1067
GSM_Phone Phone
Definition: gsmstate.h:1431
#define PRINT_LOG_ERROR(err)
Definition: api.c:28
#define CHECK_PHONE_CONNECTION()
Definition: api.c:38
GSM_Phone_Functions * Functions
Definition: gsmstate.h:1373

§ GSM_PlayTone()

GSM_Error GSM_PlayTone ( GSM_StateMachine s,
int  Herz,
unsigned char  Volume,
gboolean  start 
)

Plays tone.

Definition at line 1105 of file api.c.

References CHECK_PHONE_CONNECTION, GSM_Phone::Functions, _GSM_StateMachine::Phone, GSM_Phone_Functions::PlayTone, and PRINT_LOG_ERROR.

1106 {
1107  GSM_Error err;
1108 
1110 
1111  err = s->Phone.Functions->PlayTone(s, Herz, Volume, start);
1112  PRINT_LOG_ERROR(err);
1113  return err;
1114 }
GSM_Error
Definition: gammu-error.h:23
GSM_Phone Phone
Definition: gsmstate.h:1431
#define PRINT_LOG_ERROR(err)
Definition: api.c:28
#define CHECK_PHONE_CONNECTION()
Definition: api.c:38
GSM_Error(* PlayTone)(GSM_StateMachine *s, int Herz, unsigned char Volume, gboolean start)
Definition: gsmstate.h:1075
GSM_Phone_Functions * Functions
Definition: gsmstate.h:1373

§ GSM_ReadRingtoneFile()

GSM_Error GSM_ReadRingtoneFile ( char *  FileName,
GSM_Ringtone ringtone 
)

Definition at line 874 of file gsmring.c.

References GSM_NoteRingtone::AllNotesScale, dbgprintf, EncodeUnicode(), ERR_CANTOPENFILE, ERR_FILENOTSUPPORTED, ERR_MOREMEMORY, ERR_UNKNOWN, FALSE, GSM_Ringtone::Format, GSM_MAX_RINGTONE_NAME_LENGTH, loadbin(), loadcommunicator(), loadmmf(), loadott(), loadpuremidi(), loadre(), loadrttl(), GSM_Ringtone::Name, GSM_Ringtone::NoteTone, RING_MIDI, RING_MMF, RING_NOKIABINARY, and RING_NOTETONE.

875 {
876  FILE *file;
877  unsigned char buffer[300];
878  GSM_Error error = ERR_UNKNOWN;
879  size_t readbytes;
880  char *file_only_name;
881  size_t len;
882 
883  dbgprintf(NULL, "Loading ringtone %s\n",FileName);
884  file = fopen(FileName, "rb");
885  if (file == NULL) return ERR_CANTOPENFILE;
886 
887  file_only_name = strrchr(FileName, '/');
888  if (file_only_name == NULL) {
889  file_only_name = strrchr(FileName, '\\');
890  } else {
891  file_only_name++;
892  }
893  if (file_only_name == NULL) {
894  file_only_name = FileName;
895  } else {
896  file_only_name++;
897  }
898  len = strlen(file_only_name);
899  if (len > GSM_MAX_RINGTONE_NAME_LENGTH){
900  fclose(file);
901  return ERR_MOREMEMORY;
902  }
903 
904  EncodeUnicode(ringtone->Name, file_only_name, len);
905 
906  /* Read the header of the file. */
907  readbytes = fread(buffer, 1, 4, file);
908  if (ringtone->Format == 0x00 && readbytes == 4) {
909  ringtone->Format = RING_NOTETONE;
910  if (buffer[0]==0x00 && buffer[1]==0x00 &&
911  buffer[2]==0x0C && buffer[3]==0x01) {
912  ringtone->Format = RING_NOKIABINARY;
913  }
914  if (buffer[0]==0x00 && buffer[1]==0x00 &&
915  buffer[2]==0x00) {
916  ringtone->Format = RING_NOKIABINARY;
917  }
918  if (buffer[0]==0x4D && buffer[1]==0x54 &&
919  buffer[2]==0x68 && buffer[3]==0x64) {
920  ringtone->Format = RING_MIDI;
921  }
922  if (buffer[0]==0x4D && buffer[1]==0x4D &&
923  buffer[2]==0x4D && buffer[3]==0x44) {
924  ringtone->Format = RING_MMF;
925  }
926  if (buffer[0]=='R' && buffer[1]=='I' &&
927  buffer[2]=='F' && buffer[3]=='F') {
928  dbgprintf(NULL, "RIFF is not supported for loading!\n");
929  fclose(file);
930  return ERR_FILENOTSUPPORTED;
931  }
932  }
933  rewind(file);
934  switch (ringtone->Format) {
935  case RING_NOTETONE:
936  if (buffer[0]==0x02 && buffer[1]==0x4A) {
937  error=loadott(file,ringtone);
938  } else if (buffer[0]==0xC7 && buffer[1]==0x45) {
939  error=loadcommunicator(file,ringtone);
940  } else {
941  error=loadrttl(file,ringtone);
942  }
943  ringtone->NoteTone.AllNotesScale=FALSE;
944  break;
945  case RING_NOKIABINARY:
946  if (buffer[0]==0x00 && buffer[1]==0x00 &&
947  buffer[2]==0x0C && buffer[3]==0x01) {
948  error=loadbin(file,ringtone);
949  }
950  if (buffer[0]==0x00 && buffer[1]==0x00 &&
951  buffer[2]==0x00) {
952  error=loadre(file,ringtone);
953  }
954  break;
955  case RING_MIDI:
956  error = loadpuremidi(file,ringtone);
957  break;
958  case RING_MMF:
959  error = loadmmf(file,ringtone);
960  break;
961  default:
962  error = ERR_FILENOTSUPPORTED;
963  break;
964  }
965  fclose(file);
966  return error ;
967 }
unsigned char Name[(GSM_MAX_RINGTONE_NAME_LENGTH+1) *2]
static GSM_Error loadott(FILE *file, GSM_Ringtone *ringtone)
Definition: gsmring.c:771
GSM_RingtoneFormat Format
static GSM_Error loadcommunicator(FILE *file, GSM_Ringtone *ringtone)
Definition: gsmring.c:781
static GSM_Error loadmmf(FILE *file, GSM_Ringtone *ringtone)
Definition: gsmring.c:829
static GSM_Error loadbin(FILE *file, GSM_Ringtone *ringtone)
Definition: gsmring.c:800
GSM_Error
Definition: gammu-error.h:23
#define GSM_MAX_RINGTONE_NAME_LENGTH
Definition: gammu-limits.h:232
GSM_NoteRingtone NoteTone
static GSM_Error loadrttl(FILE *file, GSM_Ringtone *ringtone)
Definition: gsmring.c:537
void EncodeUnicode(unsigned char *dest, const char *src, size_t len)
Definition: coding.c:301
#define FALSE
Definition: gammu-types.h:25
static GSM_Error loadre(FILE *file, GSM_Ringtone *ringtone)
Definition: gsmring.c:853
static GSM_Error loadpuremidi(FILE *file, GSM_Ringtone *ringtone)
Definition: gsmring.c:819
#define dbgprintf
Definition: debug.h:72
gboolean AllNotesScale

§ GSM_RingtoneConvert()

GSM_Error GSM_RingtoneConvert ( GSM_Ringtone dest,
GSM_Ringtone src,
GSM_RingtoneFormat  Format 
)

Definition at line 1543 of file gsmring.c.

References Binary2RTTL(), CopyUnicodeString(), ERR_NONE, ERR_NOTIMPLEMENTED, GSM_Ringtone::Format, GSM_Ringtone::Name, RING_NOKIABINARY, RING_NOTETONE, and RTTL2Binary().

1544 {
1545  dest->Format = Format;
1546  CopyUnicodeString(dest->Name,src->Name);
1547  if (src->Format==RING_NOTETONE && Format==RING_NOKIABINARY) {
1548  RTTL2Binary(dest, src);
1549  return ERR_NONE;
1550  }
1551  if (src->Format==RING_NOKIABINARY && Format==RING_NOTETONE) {
1552  Binary2RTTL(dest, src);
1553  return ERR_NONE;
1554  }
1555  /* The same source and target format */
1556  if (src->Format==Format) {
1557  memcpy(dest,src,sizeof(GSM_Ringtone));
1558  return ERR_NONE;
1559  }
1560  return ERR_NOTIMPLEMENTED;
1561 }
unsigned char Name[(GSM_MAX_RINGTONE_NAME_LENGTH+1) *2]
GSM_RingtoneFormat Format
void CopyUnicodeString(unsigned char *Dest, const unsigned char *Source)
Definition: coding.c:1192
static void RTTL2Binary(GSM_Ringtone *dest, GSM_Ringtone *src)
Definition: gsmring.c:1250
static void Binary2RTTL(GSM_Ringtone *dest, GSM_Ringtone *src)
Definition: gsmring.c:1328

§ GSM_RTTLGetTempo()

int GSM_RTTLGetTempo ( int  Beats)

Definition at line 979 of file gsmring.c.

References SM_BeatsPerMinute.

Referenced by GSM_EncodeNokiaRTTLRingtone().

980 {
981  int i=0;
982 
983  while (Beats > SM_BeatsPerMinute[i] && SM_BeatsPerMinute[i] != 900) i++;
984 
985  return i<<3;
986 }
static int SM_BeatsPerMinute[]
Definition: gsmring.c:972

§ GSM_SaveRingtoneFile()

GSM_Error GSM_SaveRingtoneFile ( char *  FileName,
GSM_Ringtone ringtone 
)

Definition at line 494 of file gsmring.c.

References ERR_CANTOPENFILE, ERR_UNKNOWN, GSM_Ringtone::Format, GSM_SaveRingtoneIMelody(), GSM_SaveRingtoneMidi(), GSM_SaveRingtoneOtt(), GSM_SaveRingtoneRttl(), GSM_SaveRingtoneWav(), RING_MIDI, RING_MMF, RING_NOKIABINARY, RING_NOTETONE, savebin(), savemmf(), and savepuremidi().

495 {
496  FILE *file;
497  GSM_Error error = ERR_UNKNOWN;;
498 
499 
500  file = fopen(FileName, "wb");
501  if (file == NULL) return ERR_CANTOPENFILE;
502 
503  switch (ringtone->Format) {
504  case RING_NOTETONE:
505  if (strstr(FileName,".ott")) {
506  error = GSM_SaveRingtoneOtt(file,ringtone);
507  } else if (strstr(FileName,".rng")) {
508  error = GSM_SaveRingtoneOtt(file,ringtone);
509  } else if (strstr(FileName,".mid")) {
510  error = GSM_SaveRingtoneMidi(file,ringtone);
511  } else if (strstr(FileName,".imy")) {
512  error = GSM_SaveRingtoneIMelody(file,ringtone);
513  } else if (strstr(FileName,".ime")) {
514  error = GSM_SaveRingtoneIMelody(file,ringtone);
515  } else if (strstr(FileName,".wav")) {
516  error = GSM_SaveRingtoneWav(file,ringtone);
517  } else {
518  error = GSM_SaveRingtoneRttl(file, ringtone);
519  }
520  break;
521  case RING_NOKIABINARY:
522  error = savebin(file, ringtone);
523  break;
524  case RING_MIDI:
525  error = savepuremidi(file, ringtone);
526  break;
527  case RING_MMF:
528  error = savemmf(file, ringtone);
529  break;
530  }
531 
532  fclose(file);
533 
534  return error;
535 }
GSM_Error GSM_SaveRingtoneMidi(FILE *file, GSM_Ringtone *ringtone)
Definition: gsmring.c:413
GSM_RingtoneFormat Format
GSM_Error
Definition: gammu-error.h:23
static GSM_Error savemmf(FILE *file, GSM_Ringtone *ringtone)
Definition: gsmring.c:193
GSM_Error GSM_SaveRingtoneRttl(FILE *file, GSM_Ringtone *ringtone)
Definition: gsmring.c:201
static GSM_Error savebin(FILE *file, GSM_Ringtone *ringtone)
Definition: gsmring.c:169
static GSM_Error savepuremidi(FILE *file, GSM_Ringtone *ringtone)
Definition: gsmring.c:185
GSM_Error GSM_SaveRingtoneWav(FILE *file, GSM_Ringtone *ringtone)
Definition: gsmring.c:105
GSM_Error GSM_SaveRingtoneIMelody(FILE *file, GSM_Ringtone *ringtone)
Definition: gsmring.c:377
GSM_Error GSM_SaveRingtoneOtt(FILE *file, GSM_Ringtone *ringtone)
Definition: gsmring.c:481

§ GSM_SaveRingtoneIMelody()

GSM_Error GSM_SaveRingtoneIMelody ( FILE *  file,
GSM_Ringtone ringtone 
)

Definition at line 377 of file gsmring.c.

References chk_fwrite, ERR_NONE, ERR_WRITING_FILE, GSM_EncodeEMSSound(), GSM_Ring_IMelody12, and TRUE.

Referenced by GSM_SaveRingtoneFile().

378 {
379  char Buffer[2000];
380  size_t i=2000;
381 
382  GSM_EncodeEMSSound(ringtone, Buffer, &i, GSM_Ring_IMelody12, TRUE);
383 
384  chk_fwrite(Buffer, 1, i, file);
385  return ERR_NONE;
386 fail:
387  return ERR_WRITING_FILE;
388 }
#define TRUE
Definition: gammu-types.h:28
unsigned char GSM_EncodeEMSSound(GSM_Ringtone *ringtone, unsigned char *package, size_t *maxlength, GSM_RingtoneVersion version, gboolean start)
Definition: gsmring.c:1565
#define chk_fwrite(data, size, count, file)
Definition: gsmring.c:37

§ GSM_SaveRingtoneMidi()

GSM_Error GSM_SaveRingtoneMidi ( FILE *  file,
GSM_Ringtone ringtone 
)

Definition at line 413 of file gsmring.c.

References chk_fwrite, GSM_NoteRingtone::Commands, ERR_NONE, ERR_WRITING_FILE, FALSE, GSM_RingNoteGetFullDuration(), GSM_RingNote::Note, GSM_RingCommand::Note, Note_C, Note_H, Note_Pause, GSM_Ringtone::NoteTone, GSM_NoteRingtone::NrCommands, RING_Note, GSM_RingNote::Scale, GSM_RingNote::Tempo, TRUE, GSM_RingCommand::Type, and WriteVarLen().

Referenced by GSM_SaveRingtoneFile().

414 {
415  int pause_time = 0, duration, i, note=0, length = 20;
416  size_t current = 26;
417  gboolean started = FALSE;
418  GSM_RingNote *Note;
419  unsigned char midifile[3000] = {
420  0x4D, 0x54, 0x68, 0x64, /* MThd */
421  0x00, 0x00, 0x00, 0x06, /* chunk length */
422  0x00, 0x00, /* format 0 */
423  0x00, 0x01, /* one track */
424  0x00, 0x20, /* 32 per quarter note */
425  0x4D, 0x54, 0x72, 0x6B, /* MTrk */
426  0x00, 0x00, 0x00, 0x00, /* chunk length */
427  0x00, 0xFF, 0x51, 0x03, /* tempo meta event */
428  0x00, 0x00, 0x00}; /* 3 bytes for us for a quarter note */
429 
430  for (i = 0; i < ringtone->NoteTone.NrCommands; i++) {
431  if (ringtone->NoteTone.Commands[i].Type == RING_Note) {
432  Note = &ringtone->NoteTone.Commands[i].Note;
433  if (!started) {
434  /* readmid does not read pauses at the beginning */
435  if (Note->Note != Note_Pause) {
436  /* FIXME: we need add tempo before each note or so... */
437  duration = 60000000/Note->Tempo;
438 
439  midifile[current++] = (unsigned char)(duration >> 16);
440  midifile[current++] = (unsigned char)(duration >> 8);
441  midifile[current++] = (unsigned char)duration;
442 
443  started = TRUE;
444  }
445  }
446  if (!started) continue;
447  duration = GSM_RingNoteGetFullDuration(*Note);
448  if (Note->Note == Note_Pause) {
449  pause_time += duration;
450  } else {
451  if (Note->Note >= Note_C && Note->Note <= Note_H) {
452  note = Note->Note/16 + 12 * Note->Scale - 1;
453  }
454 
455  WriteVarLen(midifile,&current,pause_time);
456  pause_time=0;
457  midifile[current++]=0x90; /* note on */
458  midifile[current++]=note;
459  midifile[current++]=0x64; /* forte */
460 
461  WriteVarLen(midifile,&current,duration);
462  midifile[current++]=0x80; /* note off */
463  midifile[current++]=note;
464  midifile[current++]=0x64;
465  }
466  }
467  }
468  midifile[current++] = 0x00;
469  midifile[current++] = 0xFF; /* track end */
470  midifile[current++] = 0x2F;
471  midifile[current++] = 0x00;
472  midifile[length++] = (current-22) >> 8;
473  midifile[length] = current-22;
474 
475  chk_fwrite(midifile,1,current,file);
476  return ERR_NONE;
477 fail:
478  return ERR_WRITING_FILE;
479 }
GSM_RingCommand Commands[GSM_MAX_RINGTONE_NOTES]
GSM_RingNoteNote Note
GSM_RingNoteScale Scale
GSM_RingCommandType Type
GSM_NoteRingtone NoteTone
int gboolean
Definition: gammu-types.h:23
#define FALSE
Definition: gammu-types.h:25
int GSM_RingNoteGetFullDuration(GSM_RingNote Note)
Definition: gsmring.c:76
static void WriteVarLen(unsigned char *midifile, size_t *current, long value)
Definition: gsmring.c:390
#define TRUE
Definition: gammu-types.h:28
GSM_RingNote Note
#define chk_fwrite(data, size, count, file)
Definition: gsmring.c:37

§ GSM_SaveRingtoneOtt()

GSM_Error GSM_SaveRingtoneOtt ( FILE *  file,
GSM_Ringtone ringtone 
)

Definition at line 481 of file gsmring.c.

References chk_fwrite, ERR_NONE, ERR_WRITING_FILE, and GSM_EncodeNokiaRTTLRingtone().

Referenced by GSM_SaveRingtoneFile().

482 {
483  char Buffer[2000];
484  size_t i=2000;
485 
486  GSM_EncodeNokiaRTTLRingtone(ringtone, Buffer, &i);
487 
488  chk_fwrite(Buffer, 1, i, file);
489  return ERR_NONE;
490 fail:
491  return ERR_WRITING_FILE;
492 }
unsigned char GSM_EncodeNokiaRTTLRingtone(GSM_Ringtone *ringtone, unsigned char *package, size_t *maxlength)
Definition: gsmring.c:992
#define chk_fwrite(data, size, count, file)
Definition: gsmring.c:37

§ GSM_SaveRingtoneRttl()

GSM_Error GSM_SaveRingtoneRttl ( FILE *  file,
GSM_Ringtone ringtone 
)

Definition at line 201 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, Duration_INVALID, GSM_RingNote::DurationSpec, ERR_NONE, FALSE, INVALIDStyle, GSM_Ringtone::Name, NaturalStyle, NoSpecialDuration, 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_Pause, GSM_Ringtone::NoteTone, GSM_NoteRingtone::NrCommands, RING_Note, GSM_RingNote::Scale, Scale_14080, Scale_55, StaccatoStyle, GSM_RingNote::Style, GSM_RingNote::Tempo, TRUE, and GSM_RingCommand::Type.

Referenced by GSM_SaveRingtoneFile().

202 {
203  GSM_RingNoteScale DefNoteScale;
204  GSM_RingNoteDuration DefNoteDuration;
205 
206  GSM_RingNoteStyle DefNoteStyle=0;
207  int DefNoteTempo=0;
208 
209  gboolean started = FALSE, firstcomma = TRUE;
210  GSM_RingNote *Note;
211 
212  unsigned char buffer[15];
213  int i,j,k=0;
214 
215  /* Saves ringtone name */
216  fprintf(file,"%s:",DecodeUnicodeString(ringtone->Name));
217 
218  /* Find the most frequently used duration */
219  for (i=0;i<6;i++) buffer[i]=0;
220  for (i=0;i<ringtone->NoteTone.NrCommands;i++) {
221  if (ringtone->NoteTone.Commands[i].Type == RING_Note) {
222  Note = &ringtone->NoteTone.Commands[i].Note;
223  /* some durations need 2 bytes in file, some 1 */
224  /* Typecasting to silent GCC warning, Duration is usually unsigned */
225  if ((int)Note->Duration >= Duration_Full && Note->Duration <= Duration_1_8) {
226  buffer[Note->Duration/32]++;
227  }
228  if (Note->Duration >= Duration_1_16 && Note->Duration <= Duration_1_32) {
229  buffer[Note->Duration/32]+=2;
230  }
231  }
232  }
233  /* Now find the most frequently used */
234  j=0;
235  for (i=0;i<6;i++) {
236  if (buffer[i]>j) {
237  k=i;
238  j=buffer[i];
239  }
240  }
241  /* Finally convert the default duration */
242  DefNoteDuration = k * 32;
243  dbgprintf(NULL, "DefNoteDuration=%d\n", DefNoteDuration);
244  switch (DefNoteDuration) {
245  case Duration_INVALID: break;
246  case Duration_Full:fprintf(file,"d=1"); break;
247  case Duration_1_2 :fprintf(file,"d=2"); break;
248  case Duration_1_4 :fprintf(file,"d=4"); break;
249  case Duration_1_8 :fprintf(file,"d=8"); break;
250  case Duration_1_16:fprintf(file,"d=16");break;
251  case Duration_1_32:fprintf(file,"d=32");break;
252  }
253 
254  /* Find the most frequently used scale */
255  for (i=0;i<9;i++) buffer[i]=0;
256  for (i=0;i<ringtone->NoteTone.NrCommands;i++) {
257  if (ringtone->NoteTone.Commands[i].Type == RING_Note) {
258  Note = &ringtone->NoteTone.Commands[i].Note;
259  if (Note->Note!=Note_Pause &&
260  Note->Scale >= Scale_55 && Note->Scale <= Scale_14080) {
261  buffer[Note->Scale - 1]++;
262  }
263  }
264  }
265  j=0;
266  for (i=0;i<9;i++) {
267  if (buffer[i]>j) {
268  k = i;
269  j=buffer[i];
270  }
271  }
272  DefNoteScale = k + 1;
273  /* Save the default scale */
274  fprintf(file,",o=%i,",DefNoteScale);
275  dbgprintf(NULL, "DefNoteScale=%d\n", DefNoteScale);
276 
277  for (i=0;i<ringtone->NoteTone.NrCommands;i++) {
278  if (ringtone->NoteTone.Commands[i].Type != RING_Note) continue;
279 
280  Note = &ringtone->NoteTone.Commands[i].Note;
281 
282  /* Trick from PPM Edit */
283  if (Note->DurationSpec == DoubleDottedNote) {
284  switch (Note->Duration) {
285  case Duration_INVALID: break;
286  case Duration_Full:Note->Duration = Duration_Full;break;
287  case Duration_1_2 :Note->Duration = Duration_Full;break;
288  case Duration_1_4 :Note->Duration = Duration_1_2; break;
289  case Duration_1_8 :Note->Duration = Duration_1_4; break;
290  case Duration_1_16:Note->Duration = Duration_1_8; break;
291  case Duration_1_32:Note->Duration = Duration_1_16;break;
292  }
294  }
295 
296  if (!started) {
297  DefNoteTempo=Note->Tempo;
298  DefNoteStyle=Note->Style;
299  switch (Note->Style) {
300  case StaccatoStyle : fprintf(file,"s=S,"); break;
301  case NaturalStyle : fprintf(file,"s=N,"); break;
302  case ContinuousStyle : break;
303  case INVALIDStyle: break;
304  }
305  /* Save the default tempo */
306  fprintf(file,"b=%i:",DefNoteTempo);
307  dbgprintf(NULL, "DefNoteTempo=%d\n", DefNoteTempo);
308  started = TRUE;
309  firstcomma = TRUE;
310  }
311 
312  if (Note->Style!=DefNoteStyle) {
313  /* And a separator */
314  if (!firstcomma) fprintf(file,",");
315  firstcomma = FALSE;
316  DefNoteStyle=Note->Style;
317  switch (Note->Style) {
318  case StaccatoStyle : fprintf(file,"s=S"); break;
319  case NaturalStyle : fprintf(file,"s=N"); break;
320  case ContinuousStyle: fprintf(file,"s=C"); break;
321  case INVALIDStyle: break;
322  }
323  }
324  if (Note->Tempo!=DefNoteTempo) {
325  /* And a separator */
326  if (!firstcomma) fprintf(file,",");
327  firstcomma = FALSE;
328  DefNoteTempo=Note->Tempo;
329  fprintf(file,"b=%i",DefNoteTempo);
330  }
331  /* This note has a duration different than the default. We must save it */
332  if (Note->Duration!=DefNoteDuration) {
333  /* And a separator */
334  if (!firstcomma) fprintf(file,",");
335  firstcomma = FALSE;
336  switch (Note->Duration) {
337  case Duration_INVALID: break;
338  case Duration_Full:fprintf(file,"1"); break;
339  case Duration_1_2 :fprintf(file,"2"); break;
340  case Duration_1_4 :fprintf(file,"4"); break;
341  case Duration_1_8 :fprintf(file,"8"); break;
342  case Duration_1_16:fprintf(file,"16");break;
343  case Duration_1_32:fprintf(file,"32");break;
344  }
345  } else {
346  /* And a separator */
347  if (!firstcomma) fprintf(file,",");
348  firstcomma = FALSE;
349  }
350  /* Now save the actual note */
351  switch (Note->Note) {
352  case Note_C :fprintf(file,"c"); break;
353  case Note_Cis:fprintf(file,"c#"); break;
354  case Note_D :fprintf(file,"d"); break;
355  case Note_Dis:fprintf(file,"d#"); break;
356  case Note_E :fprintf(file,"e"); break;
357  case Note_F :fprintf(file,"f"); break;
358  case Note_Fis:fprintf(file,"f#"); break;
359  case Note_G :fprintf(file,"g"); break;
360  case Note_Gis:fprintf(file,"g#"); break;
361  case Note_A :fprintf(file,"a"); break;
362  case Note_Ais:fprintf(file,"a#"); break;
363  case Note_H :fprintf(file,"h"); break;
364  default :fprintf(file,"p"); break; /*Pause ?*/
365  }
366  switch (Note->DurationSpec) {
367  case DottedNote : fprintf(file,"."); break;
368  default : break;
369  }
370  if (Note->Note!=Note_Pause && Note->Scale != DefNoteScale) {
371  fprintf(file,"%i",Note->Scale);
372  }
373  }
374  return ERR_NONE;
375 }
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_RingNoteDuration
GSM_RingNote Note

§ GSM_SaveRingtoneWav()

GSM_Error GSM_SaveRingtoneWav ( FILE *  file,
GSM_Ringtone ringtone 
)

Definition at line 105 of file gsmring.c.

References chk_fwrite, GSM_NoteRingtone::Commands, ERR_NONE, ERR_WRITING_FILE, GSM_RingNoteGetFrequency(), GSM_RingNoteGetFullDuration(), GSM_RingCommand::Note, GSM_Ringtone::NoteTone, GSM_NoteRingtone::NrCommands, PI, RING_Note, GSM_RingCommand::Type, and WAV_SAMPLE_RATE.

Referenced by GSM_SaveRingtoneFile().

106 {
107 
108  unsigned char WAV_Header[] = {
109  'R','I','F','F',
110  0x00,0x00,0x00,0x00, /* Length */
111  'W','A','V','E'};
112  unsigned char FMT_Header[] = {'f','m','t',' ',
113  0x10,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x44,0xac,
114  0x00,0x00,0x88,0x58,0x01,0x00,0x02,0x00,0x10,0x00};
115  unsigned char DATA_Header[] = {
116  'd','a','t','a',
117  0x00,0x00,0x00,0x00}; /* Length */
118  short DATA;
119  long wavfilesize;
120  GSM_RingNote *Note;
121  int i;
122  size_t j,length=0, duration;
123  double phase=0,phase_step;
124 
125  chk_fwrite(&WAV_Header, 1, sizeof(WAV_Header), file);
126  chk_fwrite(&FMT_Header, 1, sizeof(FMT_Header), file);
127  chk_fwrite(&DATA_Header, 1, sizeof(DATA_Header), file);
128 
129  for (i=0;i<ringtone->NoteTone.NrCommands;i++) {
130  if (ringtone->NoteTone.Commands[i].Type == RING_Note) {
131  Note = &ringtone->NoteTone.Commands[i].Note;
132 
133  phase_step = GSM_RingNoteGetFrequency(*Note);
134  phase_step *= WAV_SAMPLE_RATE * 1.5;
135 
136  duration = GSM_RingNoteGetFullDuration(*Note);
137  duration *= WAV_SAMPLE_RATE / 70;
138 
139  for (j = 0; j < duration; j++) {
140  DATA = ((int)(sin(phase*PI) * 50000));
141  chk_fwrite(&DATA, sizeof(short), 1, file);
142  phase = phase + phase_step;
143  length++;
144  }
145  }
146  }
147 
148  wavfilesize = sizeof(WAV_Header) + sizeof(FMT_Header) + sizeof(DATA_Header) + length*2;
149  WAV_Header[4] = ((unsigned char)wavfilesize % 256);
150  WAV_Header[5] = ((unsigned char)wavfilesize / 256);
151  WAV_Header[6] = ((unsigned char)wavfilesize / (256*256));
152  WAV_Header[7] = ((unsigned char)wavfilesize / (256*256*256));
153  wavfilesize = wavfilesize - 54;
154  DATA_Header[4] = ((unsigned char)wavfilesize % 256);
155  DATA_Header[5] = ((unsigned char)wavfilesize / 256);
156  DATA_Header[6] = ((unsigned char)wavfilesize / (256*256));
157  DATA_Header[7] = ((unsigned char)wavfilesize / (256*256*256));
158 
159  fseek( file, 0, SEEK_SET);
160  chk_fwrite(&WAV_Header, 1, sizeof(WAV_Header), file);
161  chk_fwrite(&FMT_Header, 1, sizeof(FMT_Header), file);
162  chk_fwrite(&DATA_Header, 1, sizeof(DATA_Header), file);
163 
164  return ERR_NONE;
165 fail:
166  return ERR_WRITING_FILE;
167 }
GSM_RingCommand Commands[GSM_MAX_RINGTONE_NOTES]
int GSM_RingNoteGetFrequency(GSM_RingNote Note)
Definition: gsmring.c:40
#define WAV_SAMPLE_RATE
Definition: gsmring.c:103
#define PI
Definition: gsmring.c:100
GSM_RingCommandType Type
GSM_NoteRingtone NoteTone
int GSM_RingNoteGetFullDuration(GSM_RingNote Note)
Definition: gsmring.c:76
GSM_RingNote Note
#define chk_fwrite(data, size, count, file)
Definition: gsmring.c:37

§ GSM_SetRingtone()

GSM_Error GSM_SetRingtone ( GSM_StateMachine s,
GSM_Ringtone Ringtone,
int *  maxlength 
)

Sets ringtone in phone.

Definition at line 1066 of file api.c.

References CHECK_PHONE_CONNECTION, GSM_Phone::Functions, _GSM_StateMachine::Phone, PRINT_LOG_ERROR, and GSM_Phone_Functions::SetRingtone.

1067 {
1068  GSM_Error err;
1069 
1071 
1072  err = s->Phone.Functions->SetRingtone(s, Ringtone, maxlength);
1073  PRINT_LOG_ERROR(err);
1074  return err;
1075 }
GSM_Error
Definition: gammu-error.h:23
GSM_Phone Phone
Definition: gsmstate.h:1431
#define PRINT_LOG_ERROR(err)
Definition: api.c:28
#define CHECK_PHONE_CONNECTION()
Definition: api.c:38
GSM_Phone_Functions * Functions
Definition: gsmstate.h:1373
GSM_Error(* SetRingtone)(GSM_StateMachine *s, GSM_Ringtone *Ringtone, int *maxlength)
Definition: gsmstate.h:1063

§ PHONE_Beep()

GSM_Error PHONE_Beep ( GSM_StateMachine s)

Makes phone beek using state machine interface.

Definition at line 129 of file pfunc.c.

References ERR_NONE, FALSE, GSM_Phone::Functions, _GSM_StateMachine::Phone, GSM_Phone_Functions::PlayTone, and TRUE.

130 {
131  GSM_Error error;
132 
133  error=s->Phone.Functions->PlayTone(s, 4000, 5,TRUE);
134  if (error!=ERR_NONE) return error;
135 
136  usleep(500000);
137 
138  return s->Phone.Functions->PlayTone(s,255*255,0,FALSE);
139 }
GSM_Error
Definition: gammu-error.h:23
GSM_Phone Phone
Definition: gsmstate.h:1431
#define FALSE
Definition: gammu-types.h:25
GSM_Error(* PlayTone)(GSM_StateMachine *s, int Herz, unsigned char Volume, gboolean start)
Definition: gsmstate.h:1075
GSM_Phone_Functions * Functions
Definition: gsmstate.h:1373
#define TRUE
Definition: gammu-types.h:28

§ PHONE_RTTLPlayOneNote()

GSM_Error PHONE_RTTLPlayOneNote ( GSM_StateMachine s,
GSM_RingNote  note,
gboolean  first 
)

Play one note using state machine interface.

Definition at line 94 of file pfunc.c.

References ContinuousStyle, ERR_NONE, FALSE, GSM_Phone::Functions, GSM_RingNoteGetFrequency(), GSM_RingNoteGetFullDuration(), INVALIDStyle, NaturalStyle, _GSM_StateMachine::Phone, GSM_Phone_Functions::PlayTone, StaccatoStyle, GSM_RingNote::Style, and GSM_RingNote::Tempo.

95 {
96  int duration, Hz;
97  GSM_Error error;
98 
99  Hz=GSM_RingNoteGetFrequency(note);
100 
101  error=s->Phone.Functions->PlayTone(s,Hz,5,first);
102  if (error!=ERR_NONE) return error;
103 
104  duration = GSM_RingNoteGetFullDuration(note);
105 
106  /* Is it correct ? Experimental values here */
107  switch (note.Style) {
108  case INVALIDStyle:
109  break;
110  case StaccatoStyle:
111  usleep(7500000);
112  error=s->Phone.Functions->PlayTone(s,0,0,FALSE);
113  if (error != ERR_NONE) return error;
114  usleep ((1400000000L/note.Tempo*duration)-(7500000));
115  break;
116  case ContinuousStyle:
117  usleep(1400000000L/note.Tempo*duration);
118  break;
119  case NaturalStyle:
120  usleep(1400000000L/note.Tempo*duration-50000);
121  error=s->Phone.Functions->PlayTone(s,0,0,FALSE);
122  if (error != ERR_NONE) return error;
123  usleep(50000);
124  break;
125  }
126  return ERR_NONE;
127 }
int GSM_RingNoteGetFrequency(GSM_RingNote Note)
Definition: gsmring.c:40
GSM_Error
Definition: gammu-error.h:23
GSM_Phone Phone
Definition: gsmstate.h:1431
#define FALSE
Definition: gammu-types.h:25
GSM_RingNoteStyle Style
int GSM_RingNoteGetFullDuration(GSM_RingNote Note)
Definition: gsmring.c:76
GSM_Error(* PlayTone)(GSM_StateMachine *s, int Herz, unsigned char Volume, gboolean start)
Definition: gsmstate.h:1075
GSM_Phone_Functions * Functions
Definition: gsmstate.h:1373