Annotation of Examples/SoundAndMusic/SoundKit/SoundEditor/SoundDocument.m, revision 1.1

1.1     ! root        1: /*
        !             2:  * You may freely copy, distribute and reuse the code in this example.  
        !             3:  * NeXT disclaims any warranty of any kind, expressed or implied, as to 
        !             4:  * its fitness for any particular use.
        !             5:  */
        !             6: 
        !             7: 
        !             8: #import "SoundDocument.h"
        !             9: #import "SoundController.h"
        !            10: #import "ScrollingSound.h"
        !            11: #import <soundkit/soundkit.h>
        !            12: #import <appkit/Application.h>
        !            13: #import <appkit/Window.h>
        !            14: #import <appkit/Panel.h>
        !            15: #import <appkit/Cursor.h>
        !            16: #import <stdlib.h>
        !            17: #import <string.h>
        !            18: #import <objc/NXStringTable.h>
        !            19: 
        !            20: extern int access();
        !            21: 
        !            22: @implementation SoundDocument
        !            23: 
        !            24: static void newLocation(NXPoint *p)
        !            25: {
        !            26:     static count = 0;
        !            27:     p->x += (20.0 * count);
        !            28:     p->y -= (25.0 * count);
        !            29:     count = (count > 10)? 0 : count+1;
        !            30: }
        !            31: 
        !            32: - init
        !            33: {
        !            34:     NXRect theFrame;
        !            35:     
        !            36:     [super init];
        !            37:     [NXApp loadNibSection:"SoundDocument.nib" owner:self];
        !            38:     [window setDelegate:self];
        !            39:     [window getFrame:&theFrame];
        !            40:     newLocation(&theFrame.origin);
        !            41:     [window moveTo:theFrame.origin.x :theFrame.origin.y];
        !            42:     [window makeKeyAndOrderFront:nil];
        !            43:     mySoundView = [view docView];      /* view is the ScrollingSound 
        !            44:                                           in the nib file */
        !            45:     [mySoundView setSound:[[Sound alloc] init]];
        !            46:     return self;
        !            47: }
        !            48: 
        !            49: 
        !            50: - setFileName:(char *)aName
        !            51: {
        !            52:     if (fileName)
        !            53:        free(fileName);
        !            54:     fileName = (char *)malloc(strlen(aName)+1);
        !            55:     strcpy(fileName,aName);
        !            56:     [window setTitleAsFilename:fileName];
        !            57:     return self;
        !            58: }
        !            59: 
        !            60: - (char *)fileName
        !            61: {
        !            62:     return fileName;
        !            63: }
        !            64: 
        !            65: - sound
        !            66: {
        !            67:     return [mySoundView sound];
        !            68: }
        !            69: 
        !            70: - saveError:(const char *)msg arg: (char *)arg;
        !            71: {
        !            72:     if (!stringTable)
        !            73:        stringTable = [[NXApp delegate] stringTable];
        !            74:     NXRunAlertPanel([stringTable valueForStringKey:"Save"],
        !            75:        [stringTable valueForStringKey:msg],
        !            76:        [stringTable valueForStringKey:"OK"],
        !            77:        NULL,NULL,arg);
        !            78:     return nil;
        !            79: }
        !            80: 
        !            81: - saveToFormat:templateSound fileName:(char *)fn
        !            82: {
        !            83:     if (fn) {
        !            84:        int err;
        !            85:        id theSound = [[mySoundView sound] copy];
        !            86:        if (templateSound && theSound) {
        !            87:            [theSound copySound:theSound];
        !            88:            err = [theSound convertToFormat:[templateSound dataFormat]
        !            89:                            samplingRate:[templateSound samplingRate]
        !            90:                            channelCount:[templateSound channelCount]];
        !            91:            if (err) {
        !            92:                /* The DSP is required for compression or decompression */
        !            93:                return [self saveError: 
        !            94:                        "Cannot do format conversion %s (DSP busy?)" arg:""];
        !            95:            }
        !            96:        }
        !            97:        if (!access(fn, 0)) {   /* file exists */
        !            98:            char fileBuf[1024];
        !            99:            strcpy(fileBuf,fn);
        !           100:            strcat(fileBuf,"~");
        !           101:            rename(fn,fileBuf);
        !           102:        }
        !           103:        err = [theSound writeSoundfile:fn];
        !           104:        if (err) {
        !           105:            return [self saveError:"Cannot write %s" arg:fn];
        !           106:        }
        !           107:        else 
        !           108:          [window setDocEdited:NO];
        !           109:        [theSound free];
        !           110:     }
        !           111:     return self;
        !           112: }
        !           113: 
        !           114: - save:sender
        !           115: {
        !           116:     return [self saveToFormat:nil fileName:fileName];
        !           117: }
        !           118: 
        !           119: - load:sender
        !           120: {
        !           121:     if (fileName) {
        !           122:        id newSound, oldSound = [mySoundView sound];
        !           123:        newSound = [[Sound alloc] initFromSoundfile:fileName];
        !           124:        if (newSound) {
        !           125:            if (![mySoundView setSound:newSound]) { /* not displayable */
        !           126:                if ([newSound convertToFormat:SND_FORMAT_LINEAR_16]) {
        !           127:                    if (!stringTable)
        !           128:                      stringTable = [[NXApp delegate] stringTable];
        !           129:                    NXRunAlertPanel([stringTable valueForStringKey:"Open"],
        !           130:                                    [stringTable valueForStringKey:
        !           131:                                     "Cannot convert format for display "
        !           132:                                     "(DSP busy?)"],
        !           133:                                    [stringTable valueForStringKey:"OK"],
        !           134:                                    NULL,NULL);
        !           135:                    return nil;
        !           136:                } else
        !           137:                  [mySoundView setSound:newSound];
        !           138:            }
        !           139:            [oldSound free];
        !           140:        }
        !           141:     }
        !           142:     [window setDocEdited:NO];
        !           143:     return self;
        !           144: }
        !           145: 
        !           146: - revertToSaved:sender
        !           147: {
        !           148:     if([window isDocEdited] && fileName
        !           149:             && strcmp(strrchr (fileName,'/'),"/UNTITLED")) {
        !           150:        if (!stringTable)
        !           151:            stringTable = [[NXApp delegate] stringTable];
        !           152:        if (NXRunAlertPanel([stringTable valueForStringKey:"Revert"],           
        !           153:                [stringTable valueForStringKey:"Revert to saved version"
        !           154:                    " of %s?"],
        !           155:                [stringTable valueForStringKey:"Revert"],
        !           156:                [stringTable valueForStringKey:"Cancel"], 
        !           157:                    0,fileName) == NX_ALERTDEFAULT)
        !           158:            [self load:nil];
        !           159:     }
        !           160:     return self;
        !           161: }
        !           162:   
        !           163: - play:sender
        !           164: {
        !           165:     [mySoundView play:sender];
        !           166:     return self;
        !           167: }
        !           168: 
        !           169: - stop:sender
        !           170: {
        !           171:     [mySoundView stop:sender];
        !           172:     return self;
        !           173: }
        !           174: 
        !           175: - pause:sender
        !           176: {
        !           177:     [mySoundView pause:sender];
        !           178:     return self;
        !           179: }
        !           180: 
        !           181: - resume:sender
        !           182: {
        !           183:     [mySoundView resume:sender];
        !           184:     return self;
        !           185: }
        !           186: 
        !           187: - record:sender
        !           188: {
        !           189:     [mySoundView record:sender];
        !           190:     [window setDocEdited:YES];
        !           191:     return self;
        !           192: }
        !           193: 
        !           194: - touch
        !           195: {
        !           196:     [window setDocEdited:YES];
        !           197:     return self;
        !           198: }
        !           199: 
        !           200: - setDelegate:anObject
        !           201: {
        !           202:     [mySoundView setDelegate:anObject];
        !           203:     return self;
        !           204: }
        !           205: 
        !           206: - windowDidBecomeMain:sender
        !           207: {
        !           208:     [[NXApp delegate] setDocument:self];
        !           209:     [window makeFirstResponder:mySoundView];
        !           210:     [mySoundView showCursor];
        !           211:     return self;
        !           212: }
        !           213: 
        !           214: - windowDidResignMain:sender
        !           215: {
        !           216:     id theController = [NXApp delegate];
        !           217:     if ([theController document] == self)
        !           218:        [theController setDocument:nil];
        !           219:     [mySoundView hideCursor];
        !           220:     return self;
        !           221: }
        !           222: 
        !           223: - windowDidMiniaturize:sender
        !           224: {
        !           225:     [mySoundView stop:sender];
        !           226:     [mySoundView hideCursor];
        !           227:     return self;
        !           228: }
        !           229: 
        !           230: - windowWillClose:sender
        !           231: {
        !           232:     int choice;
        !           233: 
        !           234:     if ([window isDocEdited]) {
        !           235:        if (!stringTable)
        !           236:            stringTable = [[NXApp delegate] stringTable];
        !           237:        choice = NXRunAlertPanel([stringTable valueForStringKey:"Close"],
        !           238:             [stringTable valueForStringKey:"Sound is modified.\nSave it?"],
        !           239:            [stringTable valueForStringKey:"Yes"],
        !           240:            [stringTable valueForStringKey:"No"],
        !           241:            [stringTable valueForStringKey:"Cancel"]); 
        !           242:        switch (choice) {
        !           243:            case NX_ALERTALTERNATE:
        !           244:                break;
        !           245:            case NX_ALERTDEFAULT:
        !           246:                [[NXApp delegate] save:nil];
        !           247:                break;
        !           248:            case NX_ALERTOTHER:
        !           249:                return nil;
        !           250:        }
        !           251:     }
        !           252:     [self windowDidResignMain:nil];
        !           253:     [window setDelegate:nil];
        !           254:     [self free];
        !           255:     return sender;
        !           256: }
        !           257: 
        !           258: 
        !           259: static int calcFormat(SNDSoundStruct *s)
        !           260: {
        !           261:     if (s->dataFormat == SND_FORMAT_MULAW_8)
        !           262:        return SND_FORMAT_MULAW_8;
        !           263:     else if (s->dataFormat == SND_FORMAT_INDIRECT) {
        !           264:        SNDSoundStruct **iBlock = (SNDSoundStruct **)s->dataLocation;
        !           265: 
        !           266:        if (*iBlock)
        !           267:            return (*iBlock)->dataFormat;
        !           268:        else
        !           269:            return SND_FORMAT_UNSPECIFIED;
        !           270:     } else
        !           271:        return s->dataFormat;
        !           272: }
        !           273: 
        !           274: - (BOOL)isRecordable
        !           275: {
        !           276:     int format;
        !           277:     id theSound = [mySoundView sound];
        !           278:     SNDSoundStruct *soundStruct = [theSound soundStruct];
        !           279: 
        !           280:     if (!soundStruct) return YES;
        !           281:     format = calcFormat(soundStruct);
        !           282:     if (format == SND_FORMAT_MULAW_8 &&
        !           283:        soundStruct->samplingRate == (int)SND_RATE_CODEC &&
        !           284:        soundStruct->channelCount == 1 )
        !           285:        return YES;
        !           286:     else
        !           287:        return NO;
        !           288: }
        !           289: 
        !           290: - (BOOL) isPlayable
        !           291: {
        !           292:     return [mySoundView isPlayable];
        !           293: }
        !           294: 
        !           295: @end

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.