int main(int argc, const char *argv[])
{
   ALLEGRO_FILE *master, *slice;
   ALLEGRO_PATH *tmp_path;

   const char *first_string = "Hello, World!";
   const char *second_string = "The quick brown fox jumps over the lazy dog.";
   char buffer[BUFFER_SIZE];

   (void) argc, (void) argv;

   al_init();

   master = al_make_temp_file("ex_file_slice_XXXX", &tmp_path);
   if (!master) {
      abort_example("Unable to create temporary file\n");
   }

   /* Pack both strings into the master file. */
   pack_object(master, first_string, strlen(first_string));
   pack_object(master, second_string, strlen(second_string));

   /* Seek back to the beginning of the file, as if we had just opened it */
   al_fseek(master, 0, ALLEGRO_SEEK_SET);

   /* Loop through the main file, opening a slice for each object */
   while ((slice = get_next_chunk(master))) {
      /* Note: While the slice is open, we must avoid using the master file!
         If you were dealing with packed images, this is where you would pass 'slice'
         to al_load_bitmap_f(). */

      if (al_fsize(slice) < BUFFER_SIZE) {
         /* We could have used al_fgets(), but just to show that the file slice
            is constrained to the string object, we'll read the entire slice. */
         al_fread(slice, buffer, al_fsize(slice));
         buffer[al_fsize(slice)] = 0;
         printf("Chunk of size %d: '%s'\n", (int) al_fsize(slice), buffer);
      }

      /* The slice must be closed before the next slice is opened. Closing
         the slice will advanced the master file to the end of the slice. */
      al_fclose(slice);
   }

   al_fclose(master);

   al_remove_filename(al_path_cstr(tmp_path, '/'));

   return 0;
}
Example #2
0
int main(int argc, char **argv)
{
   ALLEGRO_AUDIO_RECORDER *r;
   ALLEGRO_AUDIO_STREAM *s;
   
   ALLEGRO_EVENT_QUEUE *q;
   ALLEGRO_DISPLAY *d;
   ALLEGRO_FILE *fp = NULL;
   ALLEGRO_PATH *tmp_path = NULL;
      
   int prev = 0;
   bool is_recording = false;
   
   int n = 0; /* number of samples written to disk */
   
   (void) argc;
   (void) argv;

   if (!al_init()) {
      abort_example("Could not init Allegro.\n");
   }
   
   if (!al_init_primitives_addon()) {
      abort_example("Unable to initialize primitives addon");
   }
      
   if (!al_install_keyboard()) {
      abort_example("Unable to install keyboard");
   }
      
   if (!al_install_audio()) {
      abort_example("Unable to initialize audio addon");
   }
   
   if (!al_init_acodec_addon()) {
      abort_example("Unable to initialize acodec addon");
   }
   
   /* Note: increasing the number of channels will break this demo. Other
    * settings can be changed by modifying the constants at the top of the
    * file.
    */
   r = al_create_audio_recorder(1000, samples_per_fragment, frequency,
      audio_depth, ALLEGRO_CHANNEL_CONF_1);
   if (!r) {
      abort_example("Unable to create audio recorder");
   }
   
   s = al_create_audio_stream(playback_fragment_count,
      playback_samples_per_fragment, frequency, audio_depth,
      ALLEGRO_CHANNEL_CONF_1);      
   if (!s) {
      abort_example("Unable to create audio stream");
   }
      
   al_reserve_samples(0);
   al_set_audio_stream_playing(s, false);
   al_attach_audio_stream_to_mixer(s, al_get_default_mixer());
      
   q = al_create_event_queue();
   
   /* Note: the following two options are referring to pixel samples, and have
    * nothing to do with audio samples. */
   al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST);
   al_set_new_display_option(ALLEGRO_SAMPLES, 8, ALLEGRO_SUGGEST);
   
   d = al_create_display(320, 256);
   if (!d) {
      abort_example("Error creating display\n");
   }
      
   al_set_window_title(d, "SPACE to record. P to playback.");
   
   al_register_event_source(q, al_get_audio_recorder_event_source(r));
   al_register_event_source(q, al_get_audio_stream_event_source(s));
   al_register_event_source(q, al_get_display_event_source(d));
   al_register_event_source(q, al_get_keyboard_event_source());
   
   al_start_audio_recorder(r);
   
   while (true) {
      ALLEGRO_EVENT e;

      al_wait_for_event(q, &e);
       
      if (e.type == ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT) {
         /* We received an incoming fragment from the microphone. In this
          * example, the recorder is constantly recording even when we aren't
          * saving to disk. The display is updated every time a new fragment
          * comes in, because it makes things more simple. If the fragments
          * are coming in faster than we can update the screen, then it will be
          * a problem.
          */          
         ALLEGRO_AUDIO_RECORDER_EVENT *re = al_get_audio_recorder_event(&e);
         audio_buffer_t input = (audio_buffer_t) re->buffer;
         int sample_count = re->samples; 
         const int R = sample_count / 320;
         int i, gain = 0;
         
         /* Calculate the volume, and display it regardless if we are actively
          * recording to disk. */
         for (i = 0; i < sample_count; ++i) {
            if (gain < abs(input[i] - sample_center))
               gain = abs(input[i] - sample_center);
         }
        
         al_clear_to_color(al_map_rgb(0,0,0));
        
         if (is_recording) {
            /* Save raw bytes to disk. Assumes everything is written
             * succesfully. */
            if (fp && n < frequency / (float) samples_per_fragment * 
               max_seconds_to_record) {
               al_fwrite(fp, input, sample_count * sample_size);
               ++n;
            }

            /* Draw a pathetic visualization. It draws exactly one fragment
             * per frame. This means the visualization is dependent on the 
             * various parameters. A more thorough implementation would use this
             * event to copy the new data into a circular buffer that holds a
             * few seconds of audio. The graphics routine could then always
             * draw that last second of audio, which would cause the
             * visualization to appear constant across all different settings.
             */
            for (i = 0; i < 320; ++i) {
               int j, c = 0;
               
               /* Take the average of R samples so it fits on the screen */
               for (j = i * R; j < i * R + R && j < sample_count; ++j) {
                  c += input[j] - sample_center;
               }
               c /= R;
               
               /* Draws a line from the previous sample point to the next */
               al_draw_line(i - 1, 128 + ((prev - min_sample_val) /
                  (float) sample_range) * 256 - 128, i, 128 +
                  ((c - min_sample_val) / (float) sample_range) * 256 - 128,
                  al_map_rgb(255,255,255), 1.2);
               
               prev = c;
            }
         }
         
         /* draw volume bar */
         al_draw_filled_rectangle((gain / (float) max_sample_val) * 320, 251,
            0, 256, al_map_rgba(0, 255, 0, 128));
            
         al_flip_display();
      }
      else if (e.type == ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT) {
         /* This event is received when we are playing back the audio clip.
          * See ex_saw.c for an example dedicated to playing streams.
          */
         if (fp) {
            audio_buffer_t output = al_get_audio_stream_fragment(s);
            if (output) {
               /* Fill the buffer from the data we have recorded into the file.
                * If an error occurs (or end of file) then silence out the
                * remainder of the buffer and stop the playback.
                */
               const size_t bytes_to_read =
                  playback_samples_per_fragment * sample_size;
               size_t bytes_read = 0, i;
               
               do {
                  bytes_read += al_fread(fp, (uint8_t *)output + bytes_read,
                     bytes_to_read - bytes_read);                  
               } while (bytes_read < bytes_to_read && !al_feof(fp) &&
                  !al_ferror(fp));
               
               /* silence out unused part of buffer (end of file) */
               for (i = bytes_read / sample_size;
                  i < bytes_to_read / sample_size; ++i) {
                     output[i] = sample_center;
               }
               
               al_set_audio_stream_fragment(s, output);
               
               if (al_ferror(fp) || al_feof(fp)) {
                  al_drain_audio_stream(s);
                  al_fclose(fp);
                  fp = NULL;
               }
            }
         }
      }      
      else if (e.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
         break;
      }
      else if (e.type == ALLEGRO_EVENT_KEY_CHAR) {
         if (e.keyboard.unichar == 27) {
            /* pressed ESC */
            break;
         }
         else if (e.keyboard.unichar == ' ') {
            if (!is_recording) {
               /* Start the recording */
               is_recording = true;
               
               if (al_get_audio_stream_playing(s)) {
                  al_drain_audio_stream(s);
               }
               
               /* Reuse the same temp file for all recordings */
               if (!tmp_path) {
                  fp = al_make_temp_file("alrecXXX.raw", &tmp_path);
               }
               else {
                  if (fp) al_fclose(fp);
                  fp = al_fopen(al_path_cstr(tmp_path, '/'), "w");
               }
               
               n = 0;
            }
            else {
               is_recording = false;
               if (fp) {
                  al_fclose(fp);
                  fp = NULL;
               }
            }
         }
         else if (e.keyboard.unichar == 'p') {
            /* Play the previously recorded wav file */
            if (!is_recording) {
               if (tmp_path) {
                  fp = al_fopen(al_path_cstr(tmp_path, '/'), "r");
                  if (fp) {
                     al_set_audio_stream_playing(s, true);
                  }
               }
            }
         }
      }
   }
   
   /* clean up */
   al_destroy_audio_recorder(r);
   al_destroy_audio_stream(s);
      
   if (fp)
      al_fclose(fp);
      
   if (tmp_path) {
      al_remove_filename(al_path_cstr(tmp_path, '/'));
      al_destroy_path(tmp_path);
   }
   
   return 0;
}
Example #3
0
/*
 * Decodes map data from a <data> node
 */
static void decode_layer_data(xmlNode *data_node, ALLEGRO_MAP_LAYER *layer)
{
	char *str = g_strstrip((char *)data_node->children->content);
	int datalen = layer->width * layer->height;
	layer->data = (char *)calloc(datalen, sizeof(char));

	char *encoding = get_xml_attribute(data_node, "encoding");
	if (!encoding) {
		int i = 0;
		GSList *tiles = get_children_for_name(data_node, "tile");
		GSList *tile_item = tiles;
		while (tile_item) {
			xmlNode *tile_node = (xmlNode*)tile_item->data;
			tile_item = g_slist_next(tile_item);
			char *gid = get_xml_attribute(tile_node, "gid");
			layer->data[i] = atoi(gid);
			i++;
		}

		g_slist_free(tiles);
	}
	else if (!strcmp(encoding, "base64")) {
		// decompress
		gsize rawlen;
		unsigned char *rawdata = g_base64_decode(str, &rawlen);

		// check the compression
		char *compression = get_xml_attribute(data_node, "compression");
		if (compression != NULL) {
			if (strcmp(compression, "zlib") && strcmp(compression, "gzip")) {
				fprintf(stderr, "Error: unknown compression format '%s'\n", compression);
				return;
			}

			// set up files used by zlib to decompress the data
			ALLEGRO_PATH *srcpath;
			ALLEGRO_FILE *datasrc = al_make_temp_file("XXXXXX", &srcpath);
			al_fwrite(datasrc, rawdata, rawlen);
			al_fseek(datasrc, 0, ALLEGRO_SEEK_SET);
			//al_fclose(datasrc);
			//datasrc = al_fopen(al_path_cstr(srcpath, ALLEGRO_NATIVE_PATH_SEP), "rb");
			ALLEGRO_FILE *datadest = al_make_temp_file("XXXXXX", NULL);

			// decompress and print an error if it failed
			int status = inf(datasrc, datadest);
			if (status)
				zerr(status);

			// flush data and get the file length
			al_fflush(datadest);
			int len = al_fsize(datadest);

			// read in the file
			al_fseek(datadest, 0, ALLEGRO_SEEK_SET);
			char *data = (char *)calloc(len, sizeof(char));
			if (al_fread(datadest, data, len) != len) {
				fprintf(stderr, "Error: failed to read in map data\n");
				return;
			}

			// every tile id takes 4 bytes
			int i;
			for (i = 0; i<len; i += 4) {
				int tileid = 0;
				tileid |= data[i];
				tileid |= data[i+1] << 8;
				tileid |= data[i+2] << 16;
				tileid |= data[i+3] << 24;

				layer->data[i/4] = tileid;
			}
			/*	printf("layer dimensions: %dx%d, data length = %d\n",
						layer->width, layer->height, len); */

			al_destroy_path(srcpath);
			al_fclose(datasrc);
			al_fclose(datadest);
			al_free(data);
		}
		else {
			// TODO: verify that this still works
			int i;
			for (i = 0; i<rawlen; i += 4) {
				int tileid = 0;
				tileid |= rawdata[i];
				tileid |= rawdata[i+1] << 8;
				tileid |= rawdata[i+2] << 16;
				tileid |= rawdata[i+3] << 24;

				layer->data[i/4] = tileid;
			}
		}

		g_free(rawdata);
	}
	else if (!strcmp(encoding, "csv")) {
		int i;
		for (i = 0; i<datalen; i++) {
			char *id = strtok((i == 0 ? str : NULL), ",");
			layer->data[i] = atoi(id);
		}
	}
	else {
		fprintf(stderr, "Error: unknown encoding format '%s'\n", encoding);
	}
}