Synthé-modulaire

Quelques lamas, sur la cordillère des ondes
 
AccueilAccueil  PortailPortail  S'enregistrerS'enregistrer  Connexion  
Partagez | 
 

 Qu'est ce ...

Voir le sujet précédent Voir le sujet suivant Aller en bas 
AuteurMessage
jbfairlight
Petit lama
avatar

Messages : 7
Date d'inscription : 26/11/2010
Age : 49
Localisation : Sur le ruban de Möbius

MessageSujet: Qu'est ce ...   Ven 13 Mai - 1:29

Si ici il y a des codeurs qui aiment l'archéologie... logiciel
Crazy
Code:
/*
 *                      Copyright (c) 1993 by IRCAM
 *                          All rights reserved.
 *
 *  For any information regarding this and other IRCAM software, please
 *  send email to:
 *                              [Vous devez être inscrit et connecté pour voir ce lien]
 *
 *      $Revision: 1.1.1.1 $ IRCAM $Date: 1997/07/10 14:24:58 $
 *
 * FTS by Miller Puckette
 *
 */

/* This is the main routine for MAX. */

#import <appkit/Application.h>
#import <appkit/View.h>
#import <appkit/Menu.h>
#import <appkit/MenuCell.h>
#import <appkit/Window.h>
#import <appkit/Pasteboard.h>
#import <appkit/Listener.h>

#if defined(NEXTSTEP_3) || defined(NEXTSTEP_PC)
#import <defaults/defaults.h>
#else
#import <defaults.h>
#endif

#import <objc/List.h>
#import "mess.h"

typedef void t_wind;

#import "view.h"
#import "charlie.h"
#import <sys/param.h>
#import "fts_max.h"
#import "getvalue.h"
#import "version.h"
#import <string.h>

void *sock_new();

/* Utility for creating paths */

static const char *
makeDefaultFilename(const char *dir, const char *path)
{
  static char buf[1024];

  sprintf(buf, "%s/%s", dir, path);
 
  return buf;
}

static const char *
makeDefaultArchFilename(const char *dir, const char *path, const char *arch)
{
  static char buf[1024];

  sprintf(buf, "%s/%s/%s", dir, path, arch);
 
  return buf;
}


@interface Maxapp : Application      // override the terminate message
{
}
- maxService: (id)pasteboard
    userData:(const char *)userData
      error:(char **)msg;
@end

@implementation Maxapp
- terminate:sender
/*
 * Overridden to be sure all documents get an opportunity to be saved
 * before exiting the program.
 */
{
  int count, choice;
  id window, document;

  count = [windowList count];
  while (count--)
    {
      window = [windowList objectAt:count];
      document = [window delegate];
      if ([document respondsTo:@selector(needsSaving)] &&
     [document needsSaving])
   {
     choice = NXRunAlertPanel("Quit", "You have unsaved documents.",
              "Review Unsaved", "Quit Anyway", "Cancel");
     if (choice == NX_ALERTOTHER)
       {
         return self;
       }
     else if (choice == NX_ALERTDEFAULT)
       {
         count = [windowList count];
         while (count--)
      {
        window = [windowList objectAt:count];
        document = [window delegate];
        if ([document
         respondsTo:@selector(windowWillClose:)])
          {
            if ([document windowWillClose:window])
         {
           [window close];
         }
            else
         {
           return self;
         }
          }
      }
       }
     break;
   }
    }

  [super terminate:sender];

  return nil;
}

extern void *key_keyout_get(), *keyup_keyout_get();

- sendEvent:(NXEvent *)ev
{
  static int didit;
  if (!didit)
    [[NXApp appListener] setServicesDelegate:NXApp];
  didit = 1;

  if (ev->type == NX_KEYDOWN)
    {
      if (key_keyout_get())
   outlet_int(key_keyout_get(), (long)(ev->data.key.charCode));
    }
  else if (ev->type == NX_KEYUP)
    {
      if (keyup_keyout_get())
   outlet_int(keyup_keyout_get(), (long)(ev->data.key.charCode));
    }
  [super sendEvent:ev];
}

- maxService: (id)pasteboard
    userData:(const char *)userData
      error:(char **)msg
{
  const char *types[1];
  char *buffer, *revBuffer, *data;
  int length, i=0, j;

  [pasteboard types];

  if ([pasteboard readType:NXAsciiPboardType data:&data
        length:&length])
    {
      toolbox_sendtocp(data, length);
    }
  else *msg = "Error: Max takes text only";
  return self;
}

@end



#define POLLINTERVAL .1
static DPSTimedEntry timerno;
static float pollinterval = POLLINTERVAL;

/* this is messed up -- it can send back so much graphics the
      NeXT never hands you another event */
   
void h_domaxpoll()
{
  int wascached = post_setcache(1);
  h_dopoll();
  post_setcache(wascached);
}

void max_timefn(void *x, char *buf, int size)
{
  long foo = *(long *)buf;
  restart_settime(foo);
}

void max_startpolling()
{
  timerno = DPSAddTimedEntry(pollinterval, h_domaxpoll, (void *)0, 1);
}

void max_stoppolling()
{
  if (timerno) DPSRemoveTimedEntry(timerno);
  h_setpollfunction(0);
}

h_setpollinterval(f)
    float f;
{
  pollinterval = .05;
}

static argDesc max_argdesc[] = {
  {"help",      "help", 0,      HELP,    BOOL_VALUE,    "Print the usage message and exit"},
  {"version",    "v", "version",      OPTIONAL, BOOL_VALUE,    "Print version and exit"},
  {"NextAteThisOne", 0, 0,      INTERNAL, STRING_VALUE,  ""},
  {"NXOpen",      0,  0,      INTERNAL, STRING_VALUE,  ""},
  {"NXHost",      0,  0,      INTERNAL, STRING_VALUE,  ""},
  {"MachLaunch",  0,  0,      INTERNAL, STRING_VALUE,  ""},
  {"linkType",  "l", "linkType",  OPTIONAL, STRING_VALUE,  "Type of link: sink, socket, ispw, pipe, named_pipe"},
  {"ftsArch",    "arch", "ftsArch",  OPTIONAL, STRING_VALUE,    "fts platform architecture"},
  {"ftsHost",    "h", "ftsHost",    OPTIONAL, STRING_VALUE,  "The remote fts server host"},
  {"patchPath",  "p", "patchPath",  OPTIONAL, STRING_VALUE,  "Search path for patches"},
  {"rootDir",    "r", "rootDir",      OPTIONAL, PATH_VALUE,    "The installation root directory"},
  {"helpDir",    "helpDir", "helpDir",      OPTIONAL, PATH_VALUE,    "Help file directory"},
  {"ftsDir",    "d", "ftsDir",      OPTIONAL, PATH_VALUE,    "\tFTS executables directory"},
  {"sysDir",    "sys", "sysDir",      OPTIONAL, PATH_VALUE,    "\tFTS support file directory"},
  {"ftsName",    "n", "ftsName",      OPTIONAL, PATH_VALUE,    "Name of the FTS executable"},
  {"nBoards",    "nb", "nBoards",  OPTIONAL, INTEGER_VALUE,  "Number of Boards"},
  {"advances",  "adv", "<val, , >",  OPTIONAL, STRING_VALUE,  "Columns-separated list of scheduler advances (ISPW)"},
  {"throttle", "throttle", "<val, , >", OPTIONAL, STRING_VALUE,"Columns-separated list of 3 throttles (ISPW)"},
  {"logfile",    "logfile",  0,      OPTIONAL, BOOL_VALUE,    "Make a logfile"},
  {"minfile",    "minfile",  0,      OPTIONAL, BOOL_VALUE,    "Make a minfile for each loaded patch"},
  {"stderrCopy",  "stderr",  0,      OPTIONAL, BOOL_VALUE,    "Copy Max window to stderr"},
  {"linkOptions",  "lo", "linkOptions",  OPTIONAL, STRING_VALUE,  "Link options"},
  {"verbose",    "verbose", 0,      OPTIONAL, BOOL_VALUE,    "Verbose startup"},
  {"fontName",  "f", "fontName",  OPTIONAL, STRING_VALUE,  "Text font name"},
  {"fontSize",  "s", "fontSize",  OPTIONAL, INTEGER_VALUE,  "Text font size"},
  {"startupFile",  "c", "startupFile", OPTIONAL, PATH_VALUE,  "Startup configuration file, min format"},
  0};


static const char *
appname()
{
  static char buf[80];

  /* sprintf(buf, "Max_%d_%d",  FTS_MAJOR_RELEASE, FTS_MINOR_RELEASE); */
  sprintf(buf, "Max_Fts");
  return(buf);
}

static void
registerthem(void )
{
  struct _NXDefault def[sizeof(max_argdesc)/sizeof(argDesc) + 1];
  int i;
   
  for (i = 0; i < sizeof(max_argdesc)/sizeof(argDesc); i++)
    {
      
      def[i].name = (char *)max_argdesc[i].name;
      def[i].value = 0;
    }
  def[sizeof(max_argdesc)/sizeof(argDesc)].name = 0;
  def[sizeof(max_argdesc)/sizeof(argDesc)].value = 0;

  NXRegisterDefaults(appname(), def);
}




/* NOTE ON DEFAULTS AND SETTINGS VALUES LOCATION:
  - at startup, values (set on the command line, in the NXDefaluts database, in the User environment
    or in the .defs files, are retrieved by the getValues calls.
  - these values are then used in many different calls,
  - some values are kept in different modules after the calls. Max, the fts server, the manager and
    ftsd are modules that can't share the same memory space and have their owns values spaces.
  - the preferences and settings have their own mechanisms and values... how to maintain coherency ?

  A new policy to maintain the values coherency should rely on the general use of the getValue
  module. Some communication mechanism should avail a correct refresh of values.
 
  Some values could be known by an other module that Max (ftsd for example) that should receive
  (or request) them automaticaly.
 
  We could imagine getValue to work with lists of clients (function address + some tag) bound to
  variable names, and call the clients whenever the value changes.
 
  Max has to be cleaned, and each value (variable) should rely in a reference module (getValue..).
 
  Known modules that keep their own copy of values:
     - max/fts_max.c
   - max/t_text.c: see t_setfont, ...
   - mess/toolbox.c : see t_setdefpath,
   
  Known modules that set and get values:
     - max/charlie.m
   - max/prefer.m : uses toolbox.
   - in classes : many use toolbox.
 */

extern void utils_init(void);

main(argc, argv)
    char **argv;
{
  int        linktype;
  const char *fts_arch;
  const char *ftshost = 0;
  const char *rootDir, *sysDir;      
  int tmpi, i;
  const char *tmpc;

  /* Initialize the super default/env/site configuration system.
    Soon all of the code should be converted to use this call,
    (superset and compatible with the Next Defaults) */

  for (i = 0; i < argc; i++)
    {
      if (!argv[i])
   argv[i] = "-NextAteThisOne";
      else
   if (!strcmp("-verbose", argv[i]))
     enableErrorPrint(); /* getValue debug */
    }
   
  if (!initNameValue(appname(), max_argdesc, argc-1, argv+1))
    exit(1);
   
  if (getBoolOption("Version", 0))
    {
      printf("Max version %d.%d patch level %d %s\ncopyright 1992, 1995 IRCAM\n",    
       FTS_MAJOR_RELEASE, FTS_MINOR_RELEASE, FTS_PATCH_LEVEL, FTS_RELEASE_QUALIFICATION);   
      exit(0);
    }

  /* Note: if given in command line, already done:*/
  if (getBoolOption("verbose", 0))   enableErrorPrint(); /* getValue debug */
   
  [Maxapp new];
  setupmenus();
  registerthem(); /* @@@@@@@ WHY CALL THIS ??*/

  if (getBoolOption("stderrCopy", 0))   post_copytostd();

  utils_init(); /* Initialize symbol table */

  /**** kind of link ****/
  {
    const char *linktype_s;
      
    /* Get FTS_ARCH: */

    fts_arch = getStringOption("ftsArch", "ispw"); /* for the nextstep max, now ispw is the default */

    /*** Now determine the LINKTYPE: ****/
      
    linktype  = -1;
    linktype_s = getStringOption("linkType", 0);
      
    if (linktype_s)
      {
   if (! strcmp(linktype_s, "sink"))
     linktype = SINK_CONNECTION;
   else if (!    strcmp(linktype_s, "socket"))
     linktype = SOCKET_CONNECTION;
   else if (! strcmp(linktype_s, "pipe"))
     linktype = PIPE_CONNECTION;
   else if (! strcmp(linktype_s, "pipe"))
     linktype = PIPE_CONNECTION;
   else if (! strcmp(linktype_s, "named_pipe"))
     linktype = NAMED_PIPE_CONNECTION;
   else if (! strcmp(linktype_s, "named_pipe"))
     linktype = TTY_CONNECTION;
   else if (! strcmp(linktype_s, "ispw"))
     linktype = ISPW_CONNECTION; /* @@@@ ?? do some test ?? depend on the architecture ?? */
   else
     {
       printf("Error: connection type %s unknown on this arch.\n", linktype_s);
       cleanexit(1);
     }
      }

    if (ftshost = getStringOption("ftsHost", 0))
      {
   char *handle = (char *)malloc( strlen(ftshost) + 1);
      
   strcpy(handle, ftshost);
   ftshost = handle;
      }
      
    /*----------------------------*
      Default values:
      - if ftshost defined, but not linktype: then linktype = L_SOCKET.
      - if linktype and ftshost undefined: depends on arch:
      - L_DIRECT if some board possible,
      - L_PIPE on clients supporting pipes.
      - L_SOCKET else. (host = local)
      *-----------------------------*/

    if ((0 > (int)linktype) && (ftshost))
      {
   linktype = SOCKET_CONNECTION;   
   setStringOption("linkType", "socket");
      }
      
      
    if (0 > (int)linktype)
      {
   /* Default link, depens on arch: */
#if defined(FTS_CLIENT_USE_ISPW)
   linktype =  ISPW_CONNECTION;
   setStringOption("linkType", "ispw");

#elif (defined(FTS_CLIENT_USE_PIPES))
   linktype = PIPE_CONNECTION;
   setStringOption("linkType", "pipe");
#else
   linktype = SOCKET_CONNECTION;      
   setStringOption("linkType", "socket");
#endif
      }

    fprintf(stderr,"Max starting a %s connection to an %s fts\n",
       getStringOption("linkType", "?"), fts_arch);

  } /**** End kind of link ****/


  /**** Call this before any other h_ functions ****/

  if (! h_fts_init( linktype, getStringOption("linkName", 0), ftshost))
    {
      fprintf(stderr, "Unable to connect to FTS or to the daemon\n");
      exit(0);
    }

  /* Enable immediately the logfile if requested, so
    we get all the message logged */

  if (getBoolOption("logfile", 0))
    fts_open_log(".max_logfile", 0, 0);

  if (getBoolOption("minfile", 0))
    fts_enable_minfile();

  if (getBoolOption("verbose", 0))
    h_setverbose(1);


   
  {
    char mofo[100];
    sprintf(mofo, "Max version %d.%d patch level %d %s\ncopyright 1992, 1995 IRCAM\n",    
       FTS_MAJOR_RELEASE, FTS_MINOR_RELEASE, FTS_PATCH_LEVEL, FTS_RELEASE_QUALIFICATION);   
    pdisplay(mofo);
  }

   
  if (! strcmp(fts_arch, "ispw"))
    rootDir = getStringOption("rootDir", "/LocalApps/fts.1.3");
  else
    rootDir = getStringOption("rootDir", "/usr/local/fts.1.3");


  h_setftsdir(getStringOption("ftsDir", makeDefaultArchFilename(rootDir, "bin", fts_arch)));

  /* sysdir ignored if not ispw */
 
  if (! strcmp(fts_arch, "ispw"))
    {
      sysDir = getStringOption("sysDir", "/LocalApps/Ispw");
      h_setsysdir( sysDir);
    }

  h_setftsname( getStringOption("ftsName", "fts"));
   
  if (tmpc = getStringOption("fontName", 0))
    t_setfont(tmpc);

  if (tmpc = getStringOption("fontSize", 0))
    t_setfontsize(tmpc);


  /* Parameters that can be set in the machine file */

  /* the machine file is read *only* if the editor is running on a machine
    with the same architecture as the server; i.e. we hope we are running
    on the same machine as the server, otherwise the machine file
    make no sense
    */
     
  if (! strcmp(fts_arch, "ispw"))
    {
      /* We run ISPW on a next, so we first read the machine file,
    then, if the board option has been specified, we
    set it */

      h_read_min_file(makeDefaultFilename(sysDir, "local.cfg"));

      if (getIntOption("nBoards", -1) > 0)
   h_setnboards(getIntOption("nBoards", 0));

      h_waitnboards();   

      /* Notes that advances and throttle MUST be set after nboards;
    it is shadock shit, but not time to fix it*/

      h_setadvancesstring(getStringOption("advances", "5:5:5:5:5:5"));
      h_setthrottlestring(getStringOption("Throttle", "8:8:1"));      
    }
  else
    {
      /* other wise don't read the machine file, and set the
    system to monoprocessor */

      h_setmonoproc();
    }

  /******  blabla  *****/

  mess_init();
   
  {
    char dir[MAXPATHLEN+1];
    if (getwd(dir)) defvolume = gensym(dir);
  }

  h_start();
  max_startpolling();   

  /* Read the various config file  */

  h_read_min_file(getStringOption("startupFile", makeDefaultFilename(sysDir, "default.cfg")));

  if (! getBoolOption("-no26", 0))
    h_read_min_file(makeDefaultFilename(rootDir,
               "lib/config/twentysix.cfg"));

  if (tmpc = getStringOption("helpDir", 0))
    t_sethelppath(gensym(tmpc));
  else
    t_sethelppath(gensym(makeDefaultFilename(rootDir, "lib/help")));
   
  t_setdefpath(gensym(getStringOption("patchPath", "")));
  t_setpath(t_getdefpath());

  [NXApp run];
  fts_close_log();
  max_stoppolling();
  h_eof();
  [NXApp free];
}



nx_charlie  *charlie;   /* NXApp delegate */

setupmenus()
{
  id   myMenu,
    infomenu, filemenu, windmenu, editmenu, miscmenu, classmenu;

  charlie = [nx_charlie new];
  [NXApp setDelegate: charlie];

  /* menus */
  myMenu = [Menu newTitle:appname()];

  infomenu = [Menu newTitle:"Info"];
  [[infomenu addItem:"Info Panel..."
       action:@selector(info:)
       keyEquivalent:0]
    setTarget:charlie];
  [[infomenu addItem:"Preferences..."
       action:@selector(preferences:)
       keyEquivalent:'1']
    setTarget:charlie];
  [[infomenu addItem:"Help..."
       action:@selector(help:)
       keyEquivalent:'?']
    setTarget:charlie];
  [infomenu sizeToFit];
  [myMenu setSubmenu: infomenu
     forItem: [myMenu addItem:"Info"
           action:0
           keyEquivalent:0]];

  filemenu = [Menu newTitle:"File"];
  [[filemenu addItem:"Open..."
       action:@selector(open:)
       keyEquivalent:'o']
    setTarget:charlie];
  [[filemenu addItem:"New Patcher"
       action:@selector(new_patch:)
       keyEquivalent:'n']
    setTarget:charlie];
  [filemenu addItem:"Save"
       action:@selector(save:)
       keyEquivalent:'s'];
  [filemenu addItem:"Save as..."
       action:@selector(saveAs:)
       keyEquivalent:'S'];
  [filemenu sizeToFit];
  [myMenu setSubmenu: filemenu
     forItem: [myMenu addItem:"File"
           action:0
           keyEquivalent:0]];

  editmenu = [Menu newTitle:"Edit"];
  [editmenu addItem:"Cut"
       action:@selector(cut:)
       keyEquivalent:'x'];
  [editmenu addItem:"Copy"
       action:@selector(copy:)
       keyEquivalent:'c'];
  [editmenu addItem:"Paste"
       action:@selector(paste:)
       keyEquivalent:'v'];
  [editmenu addItem:"Duplicate"
       action:@selector(dup:)
       keyEquivalent:'d'];
  [editmenu addItem:"Select All"
       action:@selector(selectall:)
       keyEquivalent:'a'];
  [editmenu sizeToFit];
  [myMenu setSubmenu: editmenu
     forItem: [myMenu addItem:"Edit"
           action:0
           keyEquivalent:0]];


  windmenu = [Menu newTitle:"Windows"];
  [windmenu addItem:"Close"
       action:@selector(close:)
       keyEquivalent:'w'];
  [windmenu addItem:"Miniaturize"
       action:@selector(miniaturize:)
       keyEquivalent:'M'];
  [NXApp setWindowsMenu: windmenu];
  [myMenu setSubmenu: windmenu
     forItem: [myMenu addItem:"Windows"
           action:0
           keyEquivalent:0]];


  [myMenu addItem:"Print ..."
     action:@selector(print:)
     keyEquivalent:'p'];

  miscmenu = [Menu newTitle:"Font"];
  [miscmenu addItem:"9" action:@selector(s9:) keyEquivalent:0];
  [miscmenu addItem:"10" action:@selector(s10:) keyEquivalent:0];
  [miscmenu addItem:"12" action:@selector(s12:) keyEquivalent:0];
  [miscmenu addItem:"14" action:@selector(s14:) keyEquivalent:0];
  [miscmenu addItem:"16" action:@selector(s16:) keyEquivalent:0];
  [miscmenu addItem:"18" action:@selector(s18:) keyEquivalent:0];
  [miscmenu addItem:"20" action:@selector(s20:) keyEquivalent:0];
  [miscmenu addItem:"24" action:@selector(s24:) keyEquivalent:0];
  [miscmenu addItem:"FONT BOMB" action:@selector(fontbomb:) keyEquivalent:0];
  [miscmenu sizeToFit];
  [myMenu setSubmenu: miscmenu forItem: [myMenu addItem:"Font"
                  action:0 keyEquivalent:0]];

  miscmenu = [Menu newTitle:"Misc"];
  [miscmenu addItem:"Edit" action:@selector(edit:) keyEquivalent:'e'];
  [miscmenu addItem:"Stretch" action:@selector(stretch:) keyEquivalent:0];
  [miscmenu addItem:"Contract" action:@selector(contract:) keyEquivalent:0];
  [[miscmenu addItem:"Settings..."
       action:@selector(settings:) keyEquivalent:'2'] setTarget:charlie];
  [[miscmenu addItem:"Restart..."
       action:@selector(restart:) keyEquivalent:'3'] setTarget:charlie];
  [miscmenu addItem:"Inspect..."
       action:@selector(inspect:) keyEquivalent:'4'];
  [miscmenu addItem:"Find..."
       action:@selector(find:) keyEquivalent:'f'];
  [miscmenu addItem:"Find again"
       action:@selector(findagain:) keyEquivalent:'g'];
  [miscmenu sizeToFit];
  [myMenu setSubmenu: miscmenu forItem: [myMenu addItem:"Misc"
                  action:0 keyEquivalent:0]];

  [myMenu addItem:"Hide"
     action:@selector(hide:)
     keyEquivalent:'h'];
  [myMenu addItem:"Quit"
     action:@selector(terminate:)
     keyEquivalent:'q'];
  [myMenu sizeToFit];
  [NXApp setMainMenu:myMenu];
  [myMenu display];

}

cleanexit(n)
{
  h_eof();
  [NXApp free];
  exit(n);
}

id focusview()
{
  return([NXApp focusView]);
}

void max_restart()
{
  int count = [[NXApp windowList] count], i;

  /* We don't restart the sounddisks here, because in any
    case we have to reload the patch; this will restart all
    the soundservers; on the contrary, we need to close all
    the open dtd servers
    */

  dtd_close_all_servers();


  toolbox__restart();
  h_start();
  for (i=0; i<count; i++)
    {
      id window = [[NXApp windowList] objectAt:i];
      if ([window respondsTo:@selector(restart_fts)])
   [window restart_fts];
    }
}

void max_find(s, again)
    char *s;
{
  int nwind, *windows, i;
  [NXApp getWindowNumbers: &windows count:&nwind];
  for (i=0; i < nwind; i++)
    {
      id window = [NXApp findWindow: windows[i]];
      if (window && [window respondsTo:@selector(find::)])
   {
     [window find: s :again];
     return;
   }
    }
}

id max_front()
{
  int nwind, *windows, i;
  [NXApp getWindowNumbers: &windows count:&nwind];
  for (i=0; i < nwind; i++)
    {
      id window = [NXApp findWindow: windows[i]];
      if (window && [window respondsTo:@selector(wind)])
   return (window);
    }
  return (0);
}

int max_canrestart()
{
  int count = [[NXApp windowList] count], i;
  for (i=0; i<count; i++)
    {
      id window = [[NXApp windowList] objectAt:i];
      if ([window respondsTo:@selector(setinspector:)]) return (0);
    }
  return (1);
}
Crazy


Dernière édition par jbfairlight le Mer 25 Mai - 19:37, édité 1 fois
Revenir en haut Aller en bas
http://mustudio.fr/
Zeitdehner
Admin
avatar

Messages : 2594
Date d'inscription : 07/11/2010
Age : 47
Localisation : Fritland

MessageSujet: Re: Qu'est ce ...   Mer 25 Mai - 10:32

Max par ci, Max par là... il est libre Max, Mad Max, Max la menace ?! No idea Cry

_________________
[Vous devez être inscrit et connecté pour voir ce lien]
[Vous devez être inscrit et connecté pour voir ce lien]
[Vous devez être inscrit et connecté pour voir ce lien]
[Vous devez être inscrit et connecté pour voir ce lien]
Revenir en haut Aller en bas
jbfairlight
Petit lama
avatar

Messages : 7
Date d'inscription : 26/11/2010
Age : 49
Localisation : Sur le ruban de Möbius

MessageSujet: Re: Qu'est ce ...   Mer 25 Mai - 19:40

Une partie des sources en Objective-C de MAX / FTS.
Revenir en haut Aller en bas
http://mustudio.fr/
 
Qu'est ce ...
Voir le sujet précédent Voir le sujet suivant Revenir en haut 
Page 1 sur 1

Permission de ce forum:Vous ne pouvez pas répondre aux sujets dans ce forum
Synthé-modulaire :: Théories et Ressources :: Théories et pratiques des différentes synthèses :: Ressources et documentations-
Sauter vers: