diff --git a/c/gtk3/alarm-clock/alarmclock.c b/c/gtk3/alarm-clock/alarmclock.c
new file mode 100644
index 0000000..063696d
--- /dev/null
+++ b/c/gtk3/alarm-clock/alarmclock.c
@@ -0,0 +1,123 @@
+#include <math.h>
+#include <time.h>
+#include <gtk/gtk.h>
+#include <al.h>
+#include <alc.h>
+
+
+const double pi = 3.141592653589793;
+
+GtkWidget *hours[3], *minutes[3];
+GtkWidget *enable_alarm;
+
+
+// This function plays beep via OpenAL.
+// It's may be difficult to understand how it works, so just use it as is.
+// This function uses OpenAL, so you need
+//   to include <al.h> and <alc.h>
+//   and link with OpenAL library (for GCC add param: -lopenal)
+void beep() {
+  const int frequency = 440;
+  const int rate = 10000;
+
+  ALCshort samples[2000];
+  const int count = 2000;
+  
+  for(int i = 0; i < count; ++i)
+    samples[i] = (int)(32760*sin(2*pi*i*frequency/rate));
+
+  ALCdevice *device = alcOpenDevice(NULL);
+  ALCcontext *context = alcCreateContext(device, NULL);
+  alcMakeContextCurrent(context);
+
+  ALuint buffer, source;
+  alGenBuffers(1, &buffer);
+  alBufferData(buffer, AL_FORMAT_MONO16, samples, sizeof(samples), rate);
+  alGenSources(1, &source);
+  alSourcei(source, AL_BUFFER, buffer);
+  alSourcePlay(source);
+  
+  g_usleep(count*1000000/rate + 10000);
+
+  alcMakeContextCurrent(NULL);
+  alcDestroyContext(context);
+  alcCloseDevice(device);
+}
+
+gboolean timeout(gpointer data) {
+  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(enable_alarm))) {
+    time_t timer = time(NULL);
+    struct tm *t = localtime(&timer);
+    for(int i = 0; i < 3; ++i) {
+      int hour = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(hours[i]));
+      int minute = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(minutes[i]));
+      if (hour == t->tm_hour && minute == t->tm_min)
+        beep();
+    }
+  }  
+  return TRUE;
+}
+
+void activate(GtkApplication* app, gpointer data) {
+  GtkWidget *window = gtk_application_window_new (app);
+  gtk_container_set_border_width(GTK_CONTAINER(window), 10);  
+  
+  GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
+  gtk_container_add(GTK_CONTAINER(window), vbox);
+  
+  GtkWidget *label = gtk_label_new("Set following three alarm clocks,\nenable alarm\nand take a sleep.");
+  gtk_container_add(GTK_CONTAINER(vbox), label);
+  
+  for(int i = 0; i < 3; ++i) {
+    GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
+    gtk_container_add(GTK_CONTAINER(vbox), hbox);
+    
+    hours[i] = gtk_spin_button_new(NULL, 1.2, 0);
+    gtk_spin_button_set_range(GTK_SPIN_BUTTON(hours[i]), 0.0, 23.0);
+    gtk_spin_button_set_increments(GTK_SPIN_BUTTON(hours[i]), 1.0, 10.0);
+    gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(hours[i]), TRUE);
+    gtk_container_add(GTK_CONTAINER(hbox), hours[i]);
+
+    minutes[i] = gtk_spin_button_new(NULL, 1.2, 0);
+    gtk_spin_button_set_range(GTK_SPIN_BUTTON(minutes[i]), 0.0, 59.0);
+    gtk_spin_button_set_increments(GTK_SPIN_BUTTON(minutes[i]), 1.0, 10.0);
+    gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(minutes[i]), TRUE);
+    gtk_container_add(GTK_CONTAINER(hbox), minutes[i]);
+  }
+  
+  // set initial values
+  time_t timer = time(NULL);
+  struct tm *t = localtime(&timer);
+  int h = t->tm_hour;
+  int m = t->tm_min;
+  
+  gtk_spin_button_set_value(GTK_SPIN_BUTTON(hours[0]), h);
+  gtk_spin_button_set_value(GTK_SPIN_BUTTON(minutes[0]), m);
+  
+  m += 1;
+  if (m >= 60) { m -= 60; h = (h + 1)%24; }
+  gtk_spin_button_set_value(GTK_SPIN_BUTTON(hours[1]), h);
+  gtk_spin_button_set_value(GTK_SPIN_BUTTON(minutes[1]), m);
+  
+  m += 4;
+  if (m >= 60) { m -= 60; h = (h + 1)%24; }
+  gtk_spin_button_set_value(GTK_SPIN_BUTTON(hours[2]), h);
+  gtk_spin_button_set_value(GTK_SPIN_BUTTON(minutes[2]), m);
+
+  enable_alarm = gtk_check_button_new_with_label("Enable alarm");
+  gtk_container_add(GTK_CONTAINER(vbox), enable_alarm);
+  
+  gtk_widget_show_all(window);
+  
+  g_timeout_add(1000, timeout, NULL);
+}
+
+int main(int argc, char **argv) {
+  GtkApplication *application = gtk_application_new(NULL, 0);
+  g_signal_connect(application, "activate", G_CALLBACK(activate), NULL);
+  int status = g_application_run(G_APPLICATION(application), argc, argv);
+  g_object_unref(application);
+  return status;
+}
+
+
diff --git a/c/gtk3/alarm-clock/readme b/c/gtk3/alarm-clock/readme
new file mode 100644
index 0000000..89f4233
--- /dev/null
+++ b/c/gtk3/alarm-clock/readme
@@ -0,0 +1,3 @@
+this example requires OpenAL to play beeps,
+so GCC commandline to compile it becomes:
+  gcc -lm `pkg-config --cflags --libs gtk+-3.0 openal` *.c