Squeak-4.10.2.2614-src/0000775000175000017500000000000012032156447014443 5ustar piumartapiumartaSqueak-4.10.2.2614-src/Makefile0000664000175000017500000000025412032156447016104 0ustar piumartapiumartaall : .force test -d bld || mkdir bld (cd bld; ../unix/cmake/configure) (cd bld; make) install : all (cd bld; make install) clean : .force /bin/rm -rf bld .force : Squeak-4.10.2.2614-src/README0000664000175000017500000000412712032156447015327 0ustar piumartapiumartaBuilding Unix Squeak from a source archive ========================================== Executive summary ----------------- tar -xf .tar.gz cd mkdir bld cd bld ../unix/cmake/configure make Detailed instructions --------------------- 1 Unpack the sources. tar -xf Squeak-X.Y.Z.R-srca.tar.gz This will create a directory called 'Squeak-X.Y.Z.R-src'. Descend into it with 'cd Squeak-X.Y.Z.R-src'. 2 You can use the supplied interpreter sources in 'unix/src' or you can generate your own. If you generate your own then I recommend you place then in a directory next to 'unix/src' and call them something else, 'unix/vmm' for example. 3 Create a build directory. This can be anywhere you want. In this README we will 'mkdir bld' to create the build directory in 'Squeak-X.Y.Z.R-src', next to the 'unix' and 'Cross' directories. Building directly in the source tree (starting in unix) should work but is UNTESTED and UNSUPPORTED and discrouraged by CMake people too. 4 Descend into your build directory. 'cd bld'. 5 Configure your build: '../unix/cmake/configure'. (You can pass arguments to this script; run 'cmake/configure --help' to see a list of them.) 6 Build it: just type 'make', sit back, and enjoy the pretty colours (assuming your terminal supports them). This should leave you with an executable called 'squeak' in your build directory. 7 You can test the binary in-place by running 'squeak' with a path to an image file as argument; e.g: ./squeak ../../squeak.image 8 If it works, install it by typing 'make install' in your build directory. 9 If you modify the sources you can safely type 'make' in the build directory and everything affected will be rebuilt. If you want to reconfigure and rebuild only affected files, type 'cmake .' and then 'make'. If you want to rebuild everything type 'make clean' and then 'make'. If you want to reconfigure everything and then rebuild everything just delete your build directory and start again from step 3. ---- Last edited: 2009-08-30 23:55:32 by piumarta on ubuntu.piumarta.com Squeak-4.10.2.2614-src/unix/0000775000175000017500000000000012032156447015426 5ustar piumartapiumartaSqueak-4.10.2.2614-src/unix/vm-sound-ALSA/0000775000175000017500000000000012032156447017714 5ustar piumartapiumartaSqueak-4.10.2.2614-src/unix/vm-sound-ALSA/sqUnixSoundALSA.c0000644000175000017500000004725011355203245023023 0ustar piumartapiumarta/* sqUnixSoundALSA.c -- cheap and cheerful sound for Advanced Linux Sound Architecture * * Author: Ian.Piumarta@squeakland.org * * Last edited: 2010-04-01 13:48:37 by piumarta on emilia-2.local * * Copyright (C) 2006 by Ian Piumarta * All rights reserved. * * This file is part of Unix Squeak. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include "sq.h" #include #include #include #define DEVICE_NAME_LEN 128 static char sound_device[DEVICE_NAME_LEN]; /* = "default"; */ static char sound_playback[DEVICE_NAME_LEN]; /* = "Master"; */ static char sound_capture[DEVICE_NAME_LEN]; /* = "Capture"; */ #define FAIL(X) \ { \ success(false); \ return X; \ } #define snd(expr, what) \ if ((err= snd_##expr) < 0) \ { \ fprintf(stderr, "%s: %s\n", what, snd_strerror(err)); \ success(false); \ return err; \ } #define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) #define MAX(X, Y) ((X) > (Y) ? (X) : (Y)) static void sigio_save(void); static void sigio_restore(void); /* output */ #define SQ_SND_PLAY_START_THRESHOLD 7/8 #define SQ_SND_PLAY_AVAIL_MIN 4/8 static snd_pcm_t *output_handle= 0; static snd_async_handler_t *output_handler= 0; static int output_semaphore= 0; static int output_channels= 0; static int output_buffer_frames_available= 0; static snd_pcm_uframes_t output_buffer_period_size= 0; static snd_pcm_uframes_t output_buffer_size= 0; static double max_delay_frames= 0; static void output_callback(snd_async_handler_t *handler) { signalSemaphoreWithIndex(output_semaphore); output_buffer_frames_available= 1; } static sqInt sound_Stop(void) { if (output_handle) { snd_pcm_close(output_handle); output_handle= 0; sigio_restore(); } return 0; } static sqInt sound_Start(sqInt frameCount, sqInt samplesPerSec, sqInt stereo, sqInt semaIndex) { int err; snd_pcm_hw_params_t *hwparams; snd_pcm_sw_params_t *swparams; unsigned int uval; int dir; if (output_handle) sound_Stop(); output_semaphore= semaIndex; output_channels= stereo ? 2 : 1; snd(pcm_open(&output_handle, sound_device, SND_PCM_STREAM_PLAYBACK, 0), "startSound: snd_pcm_open"); snd_pcm_hw_params_alloca(&hwparams); snd_pcm_hw_params_any(output_handle, hwparams); snd_pcm_hw_params_set_access(output_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED); snd_pcm_hw_params_set_format(output_handle, hwparams, SND_PCM_FORMAT_S16_LE); snd_pcm_hw_params_set_channels(output_handle, hwparams, output_channels); uval= samplesPerSec; snd_pcm_hw_params_set_rate_near(output_handle, hwparams, &uval, &dir); output_buffer_period_size= frameCount; snd_pcm_hw_params_set_period_size_near(output_handle, hwparams, &output_buffer_period_size, &dir); snd(pcm_hw_params(output_handle, hwparams), "sound_Start: snd_pcm_hw_params"); snd_pcm_sw_params_alloca(&swparams); snd(pcm_sw_params_current(output_handle, swparams), "sound_Start: snd_pcm_sw_params_current"); snd(pcm_sw_params_set_start_threshold(output_handle, swparams, frameCount * SQ_SND_PLAY_START_THRESHOLD), "sound_Start: snd_pcm_sw_params_set_start_threshold"); snd(pcm_sw_params_set_avail_min(output_handle, swparams, frameCount * SQ_SND_PLAY_AVAIL_MIN), "sound_Start: snd_pcm_sw_parama_set_avail_min"); snd(pcm_sw_params_set_xfer_align(output_handle, swparams, 1), "sound_Start: snd_pcm_sw_params_set_xfer_align"); snd(pcm_sw_params(output_handle, swparams), "sound_Start: snd_pcm_sw_params"); snd(pcm_hw_params_get_buffer_size(hwparams, &output_buffer_size), "sound_Start: pcm_hw_params_get_buffer_size"); output_buffer_frames_available= 1; max_delay_frames= output_buffer_period_size * 2; /* set initial delay frames */ snd(pcm_nonblock(output_handle, 1), "sound_Start: snd_pcm_nonblock"); snd(async_add_pcm_handler(&output_handler, output_handle, output_callback, 0), "soundStart: snd_add_pcm_handler"); if ((err= snd_pcm_start(output_handle)) < 0) { if (err != -EPIPE) { fprintf(stderr, "snd_pcm_start(1): %s\n", snd_strerror(err)); success(false); return 0; } } if ((err= snd_pcm_prepare(output_handle)) < 0) fprintf(stderr, "snd_pcm_prepare: %s\n", snd_strerror(err)); if ((err= snd_pcm_start(output_handle)) < 0) { if (err != -EPIPE) { fprintf(stderr, "snd_pcm_start(2): %s\n", snd_strerror(err)); success(false); return 0; } } return 1; } static sqInt sound_AvailableSpace(void) { #if 1 snd_pcm_sframes_t delay; /* distance to playback point (in frames) */ snd_pcm_state_t state; /* current state of the stream */ sqInt avail= 0; /* available space for the answer (in bytes) */ if (!output_handle) return 0; snd_pcm_delay(output_handle, &delay); snd_pcm_avail_update(output_handle); state= snd_pcm_state(output_handle); /* if underrun causes, max delay is loosened */ if (state == SND_PCM_STATE_XRUN) max_delay_frames= MIN(max_delay_frames * 1.5, output_buffer_size - output_buffer_period_size); /* if the state is not running, new sound is needed because nobody can signal the semaphore */ if (delay <= max_delay_frames || state != SND_PCM_STATE_RUNNING) { avail= output_buffer_period_size; max_delay_frames= MAX(max_delay_frames * 0.9995, output_buffer_period_size); } /*fprintf(stderr, "delay=%i, ans_avail=%i, state=%i, real_delay=%.1fms\n", (int) delay, avail, state, 1000 * max_delay_frames / 22050);*/ return avail * output_channels * 2; /* bytes */ #else if (output_handle) { int count= snd_pcm_avail_update(output_handle); if (count >= 0) return count; fprintf(stderr, "sound_AvailableSpace: snd_pcm_avail_update: %s\n", snd_strerror(count)); snd_pcm_prepare(output_handle); } return 0; #endif } static sqInt sound_InsertSamplesFromLeadTime(sqInt frameCount, void *srcBufPtr, sqInt samplesOfLeadTime) FAIL(frameCount) static sqInt sound_PlaySamplesFromAtLength(sqInt frameCount, void *srcBufPtr, sqInt startIndex) { if (output_handle) { void *samples= srcBufPtr + startIndex * output_channels * 2; int count= snd_pcm_writei(output_handle, samples, frameCount); if (count < frameCount / 2) { output_buffer_frames_available= 0; } if (count < 0) { if (count == -EPIPE) /* underrun */ { int err; snd(pcm_prepare(output_handle), "sound_PlaySamples: snd_pcm_prepare"); return 0; } fprintf(stderr, "snd_pcm_writei returned %i\n", count); return 0; } return count; } success(false); return 0; } static sqInt sound_PlaySilence(void) FAIL(8192) /* input */ #define SQ_SND_REC_START_THRESHOLD 4/8 #define SQ_SND_REC_AVAIL_MIN 4/8 static snd_pcm_t *input_handle= 0; static snd_async_handler_t *input_handler= 0; static int input_semaphore= 0; static int input_channels= 0; static unsigned int input_rate= 0; static void input_callback(snd_async_handler_t *handler) { signalSemaphoreWithIndex(input_semaphore); } static sqInt sound_StopRecording(void) { if (input_handle) { snd_pcm_close(input_handle); input_handle= 0; sigio_restore(); } return 0; } static sqInt sound_StartRecording(sqInt desiredSamplesPerSec, sqInt stereo, sqInt semaIndex) { int err; snd_pcm_hw_params_t *hwparams; snd_pcm_sw_params_t *swparams; snd_pcm_uframes_t frames; int dir; if (input_handle) sound_StopRecording(); input_semaphore= semaIndex; input_channels= stereo ? 2 : 1; snd(pcm_open(&input_handle, sound_device, SND_PCM_STREAM_CAPTURE, 0), "start_SoundRecording: snd_pcm_open"); snd_pcm_hw_params_alloca(&hwparams); snd_pcm_hw_params_any(input_handle, hwparams); snd_pcm_hw_params_set_access(input_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED); snd_pcm_hw_params_set_format(input_handle, hwparams, SND_PCM_FORMAT_S16_LE); snd_pcm_hw_params_set_channels(input_handle, hwparams, input_channels); input_rate= desiredSamplesPerSec; snd_pcm_hw_params_set_rate_near(input_handle, hwparams, &input_rate, &dir); frames= 4096; snd_pcm_hw_params_set_period_size_near(input_handle, hwparams, &frames, &dir); snd(pcm_hw_params(input_handle, hwparams), "sound_StartRecording: snd_pcm_hw_params"); snd_pcm_sw_params_alloca(&swparams); snd(pcm_sw_params_current(input_handle, swparams), "sound_StartRecording: snd_pcm_sw_params_current"); snd(pcm_sw_params_set_start_threshold(input_handle, swparams, frames * SQ_SND_REC_START_THRESHOLD), "sound_StartRecording: snd_pcm_sw_params_set_start_threshold"); snd(pcm_sw_params_set_avail_min(input_handle, swparams, frames * SQ_SND_REC_AVAIL_MIN), "sound_StartRecording: snd_pcm_sw_parama_set_avail_min"); snd(pcm_sw_params_set_xfer_align(input_handle, swparams, 1), "sound_StartRecording: snd_pcm_sw_params_set_xfer_align"); snd(pcm_sw_params(input_handle, swparams), "sound_StartRecording: snd_pcm_sw_params"); snd(pcm_nonblock(input_handle, 1), "sound_StartRecording: snd_pcm_nonblock"); snd(async_add_pcm_handler(&input_handler, input_handle, input_callback, 0), "sound_StartRecording: snd_add_pcm_handler"); snd(pcm_start(input_handle), "sound_StartRecording: snd_pcm_start"); return 1; } static double sound_GetRecordingSampleRate(void) { return (double)input_rate; } static sqInt sound_RecordSamplesIntoAtLength(void *buf, sqInt startSliceIndex, sqInt bufferSizeInBytes) { if (input_handle) { void *samples= buf + (startSliceIndex * 2); int frameCount= ((bufferSizeInBytes / 2) - startSliceIndex) / input_channels; int count= snd_pcm_readi(input_handle, samples, frameCount); if (count < 0) { if (count == -EPIPE) snd_pcm_prepare(input_handle); else if (count != -EAGAIN) fprintf(stderr, "snd_pcm_readi returned %i\n", count); return 0; } return count * input_channels; } success(false); return 0; } /* mixer */ static int sound_nomixer = 0; static snd_mixer_t *mixer_handle = 0; static snd_mixer_elem_t *mixer_element = 0; static int mixer_open(char *name) { struct snd_mixer_selem_regopt smixer_options; int err; snd_mixer_selem_id_t *sid; if (sound_nomixer) return -EACCES; smixer_options.device= sound_device; snd_mixer_selem_id_alloca(&sid); snd_mixer_selem_id_set_name(sid, name); snd(mixer_open(&mixer_handle, 0), "snd_mixer_open"); snd(mixer_attach(mixer_handle, sound_device), "snd_mixer_attach"); snd(mixer_selem_register(mixer_handle, NULL, NULL), "snd_selem_register"); snd(mixer_load(mixer_handle), "snd_mixer_load"); mixer_element= snd_mixer_find_selem(mixer_handle, sid); if (!mixer_element) { fprintf(stderr, "unable to find control %s, %i\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid)); return -ENOENT; } return 0; } static void mixer_close(void) { snd_mixer_close(mixer_handle); mixer_handle= 0; } static inline void mixer_getVolume(char *name, int captureFlag, double *leftLevel, double *rightLevel) { if (mixer_open(name)) { mixer_close(); return; } if (!(captureFlag ? snd_mixer_selem_has_capture_volume : snd_mixer_selem_has_playback_volume)(mixer_element)) fprintf(stderr, "%s: no %s volume\n", name, captureFlag ? "capture" : "playback"); else { long vmin, vmax; int channel= -1; (captureFlag ? snd_mixer_selem_get_capture_volume_range : snd_mixer_selem_get_playback_volume_range)(mixer_element, &vmin, &vmax); fprintf(stderr, "%s range %li - %li\n", captureFlag ? "capture" : "playback", vmin, vmax); while (++channel <= SND_MIXER_SCHN_LAST) if ((captureFlag ? snd_mixer_selem_has_capture_channel : snd_mixer_selem_has_playback_channel)(mixer_element, channel)) { long vol; (captureFlag ? snd_mixer_selem_get_capture_volume : snd_mixer_selem_get_playback_volume)(mixer_element, channel, &vol); *leftLevel= *rightLevel= (double)(vol - vmin) / (double)(vmax - vmin); break; } while (++channel <= SND_MIXER_SCHN_LAST) if ((captureFlag ? snd_mixer_selem_has_capture_channel : snd_mixer_selem_has_playback_channel)(mixer_element, channel)) { long vol; (captureFlag ? snd_mixer_selem_get_capture_volume : snd_mixer_selem_get_playback_volume)(mixer_element, channel, &vol); *rightLevel= (double)(vol - vmin) / (double)(vmax - vmin); break; } } mixer_close(); } static inline void mixer_setVolume(char *name, int captureFlag, double leftLevel, double rightLevel) { if (mixer_open(name)) { mixer_close(); return; } if (!(captureFlag ? snd_mixer_selem_has_capture_volume : snd_mixer_selem_has_playback_volume)(mixer_element)) fprintf(stderr, "%s: no %s volume\n", name, captureFlag ? "capture" : "playback"); else { long vmin, vmax; int channel= -1; (captureFlag ? snd_mixer_selem_get_capture_volume_range : snd_mixer_selem_get_playback_volume_range)(mixer_element, &vmin, &vmax); fprintf(stderr, "playback range %li - %li\n", vmin, vmax); while (++channel <= SND_MIXER_SCHN_LAST) if ((captureFlag ? snd_mixer_selem_has_capture_channel : snd_mixer_selem_has_playback_channel)(mixer_element, channel)) { long vol= vmin + (double)(vmax - vmin) * leftLevel; (captureFlag ? snd_mixer_selem_set_capture_volume : snd_mixer_selem_set_playback_volume)(mixer_element, channel, vol); (captureFlag ? snd_mixer_selem_set_capture_switch : snd_mixer_selem_set_playback_switch)(mixer_element, channel, 1); break; } while (++channel <= SND_MIXER_SCHN_LAST) if ((captureFlag ? snd_mixer_selem_has_capture_channel : snd_mixer_selem_has_playback_channel)(mixer_element, channel)) { long vol= vmin + (double)(vmax - vmin) * rightLevel; (captureFlag ? snd_mixer_selem_set_capture_volume : snd_mixer_selem_set_playback_volume)(mixer_element, channel, vol); (captureFlag ? snd_mixer_selem_set_capture_switch : snd_mixer_selem_set_playback_switch)(mixer_element, channel, 1); break; } } mixer_close(); } static int mixer_setSwitch(char *name, int captureFlag, int parameter) { int chn; if (mixer_open(name)) { mixer_close(); return 0; } if (!(captureFlag ? snd_mixer_selem_has_capture_switch : snd_mixer_selem_has_playback_switch)(mixer_element)) { mixer_close(); return 0; } for (chn= 0; chn <= SND_MIXER_SCHN_LAST; ++chn) { if (!(captureFlag ? snd_mixer_selem_has_capture_channel : snd_mixer_selem_has_playback_channel)(mixer_element, chn)) continue; if ((captureFlag ? snd_mixer_selem_set_capture_switch : snd_mixer_selem_set_playback_switch)(mixer_element, chn, parameter) < 0) continue; } mixer_close(); return 1; } static int mixer_getSwitch(char *name, int captureFlag, int channel) { int ival; if (channel < 0 || channel > SND_MIXER_SCHN_LAST) { return -1; } if (mixer_open(name)) { mixer_close(); return -1; } if (!(captureFlag ? snd_mixer_selem_has_capture_switch : snd_mixer_selem_has_playback_switch)(mixer_element)) { mixer_close(); return -1; } if (!(captureFlag ? snd_mixer_selem_has_capture_channel : snd_mixer_selem_has_playback_channel)(mixer_element, channel)) { mixer_close(); return -1; } if ((captureFlag ? snd_mixer_selem_get_capture_switch : snd_mixer_selem_get_playback_switch)(mixer_element, channel, &ival) < 0) ival= -1; mixer_close(); return ival; } static void sound_Volume(double *left, double *right) { mixer_getVolume(sound_playback, 0, left, right); } static void sound_SetVolume(double left, double right) { mixer_setVolume(sound_playback, 0, left, right); if (strcmp("Master", sound_playback)) { /* unmute the master volume */ mixer_getVolume("Master", 0, &left, &right); mixer_setVolume("Master", 0, left, right); } } static void sound_SetRecordLevel(sqInt level) { mixer_setVolume(sound_capture, 1, (double)level / 100.0, (double)level / 100.0); } static sqInt sound_SetDevice(sqInt id, char *arg) { char *dest= NULL; if (id == 0) { if (arg == NULL) { arg= "default"; } dest= sound_device; } else if (id == 1) { if (arg == NULL) { arg= "Master"; } dest= sound_playback; } else if (id == 2) { if (arg == NULL) { arg= "Capture"; } dest= sound_capture; } if (dest) { strncpy(dest, arg, DEVICE_NAME_LEN-1); return 1; } return -1; } static sqInt sound_GetSwitch(sqInt id, sqInt captureFlag, sqInt channel) { if (id == 1) { return mixer_getSwitch(sound_playback, captureFlag, channel); } else if (id == 2) { return mixer_getSwitch(sound_capture, captureFlag, channel); } return -1; } static sqInt sound_SetSwitch(sqInt id, sqInt captureFlag, sqInt parameter) { if (id == 1) { return mixer_setSwitch(sound_playback, captureFlag, parameter); } else if (id == 2) { return mixer_setSwitch(sound_capture, captureFlag, parameter); } return -1; } /* signal support */ static void *sigio_handler= 0; static void sigio_save(void) { if (!sigio_handler) { sigio_handler= signal(SIGIO, SIG_IGN); signal(SIGIO, sigio_handler); } } static void sigio_restore(void) { if (sigio_handler && !output_handle && !input_handle) signal(SIGIO, sigio_handler); } /* module */ #include "SqSound.h" SqSoundDefine(ALSA); #include "SqModule.h" static void sound_parseEnvironment(void) { char *ev= 0; sound_SetDevice(0, NULL); sound_SetDevice(1, NULL); sound_SetDevice(2, NULL); if ( getenv("SQUEAK_NOMIXER" )) sound_nomixer= 1; if ((ev= getenv("SQUEAK_SOUNDCARD"))) sound_SetDevice(0, ev); if ((ev= getenv("SQUEAK_PLAYBACK" ))) sound_SetDevice(1, ev); if ((ev= getenv("SQUEAK_CAPTURE" ))) sound_SetDevice(2, ev); } static int sound_parseArgument(int argc, char **argv) { if (!strcmp(argv[0], "-nomixer" )) { sound_nomixer= 1; return 1; } else if (argv[1]) { if (!strcmp(argv[0], "-soundcard")) { sound_SetDevice(0, argv[1]); return 2; } if (!strcmp(argv[0], "-playback" )) { sound_SetDevice(1, argv[1]); return 2; } if (!strcmp(argv[0], "-capture" )) { sound_SetDevice(2, argv[1]); return 2; } } return 0; } static void sound_printUsage(void) { printf("\nALSA