Sisyphus
: 1 2023 | : 18631 | : 37885060
en ru br
:: /GNUstep
: gnustep-MP3ToWav

                   Gear   Bugs and FR  Repocop 

gnustep-MP3ToWav-0.4.1/000075500000000000000000000000001227754251000145625ustar00rootroot00000000000000gnustep-MP3ToWav-0.4.1/English.lproj/000075500000000000000000000000001227754251000173005ustar00rootroot00000000000000gnustep-MP3ToWav-0.4.1/English.lproj/Localizable.strings000064400000000000000000000010061227754251000231310ustar00rootroot00000000000000/***
English.lproj/Localizable.strings
updated by make_strings 2005-03-24 13:31:05 +0100
add comments above this one
***/


/*** Strings from MP3ToWavController.m ***/
/* File: MP3ToWavController.m:303 */
"Launching %@ %@" = "Launching %@ %@";
/* File: MP3ToWavController.m:325 */
"Removing file failed." = "Removing file failed.";
/* File: MP3ToWavController.m:323 */
"Removing temporary file %@." = "Removing temporary file %@.";
/* File: MP3ToWavController.m:347 */
"Terminating process." = "Terminating process.";
gnustep-MP3ToWav-0.4.1/French.lproj/000075500000000000000000000000001227754251000171145ustar00rootroot00000000000000gnustep-MP3ToWav-0.4.1/French.lproj/Localizable.strings000064400000000000000000000010531227754251000227470ustar00rootroot00000000000000/***
French.lproj/Localizable.strings
updated by make_strings 2005-03-24 13:31:05 +0100
add comments above this one
***/


/*** Strings from MP3ToWavController.m ***/
/* File: MP3ToWavController.m:303 */
"Launching %@ %@" = "Lancement %@ %@";
/* File: MP3ToWavController.m:325 */
"Removing file failed." = "La suppression du fichier a \u00e9chou\u00e9..";
/* File: MP3ToWavController.m:323 */
"Removing temporary file %@." = "Supprimer le fichier temporaire %@.";
/* File: MP3ToWavController.m:347 */
"Terminating process." = "Terminaison du processus.";
gnustep-MP3ToWav-0.4.1/GNUmakefile000064400000000000000000000012551227754251000166370ustar00rootroot00000000000000include $(GNUSTEP_MAKEFILES)/common.make

BUNDLE_NAME = MP3ToWav
BUNDLE_EXTENSION = .bundle

BUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Bundles

MP3ToWav_RESOURCE_FILES = iconMP3ToWav.tiff

MP3ToWav_OBJC_FILES = \
MP3ToWavController.m \
PlayBuffer.m \
MadFunctions.m

MP3ToWav_HEADERS = \
MP3ToWavController.h \
PlayBuffer.h \
MadFunctions.h

MP3ToWav_PRINCIPAL_CLASS = \
MP3ToWavController

ADDITIONAL_OBJCFLAGS = -Wall

ADDITIONAL_INCLUDE_DIRS += -I../.. -I../../Burn/
BUNDLE_LIBS += -lao -lmad

MP3ToWav_LANGUAGES=English German French
MP3ToWav_LOCALIZED_RESOURCE_FILES = \
Localizable.strings

include $(GNUSTEP_MAKEFILES)/bundle.make

-include GNUmakefile.postamble
gnustep-MP3ToWav-0.4.1/German.lproj/000075500000000000000000000000001227754251000171205ustar00rootroot00000000000000gnustep-MP3ToWav-0.4.1/German.lproj/Localizable.strings000064400000000000000000000010021227754251000227450ustar00rootroot00000000000000/***
German.lproj/Localizable.strings
updated by make_strings 2005-03-24 13:31:05 +0100
add comments above this one
***/


/*** Strings from MP3ToWavController.m ***/
/* File: MP3ToWavController.m:303 */
"Launching %@ %@" = "Starte %@ %@";
/* File: MP3ToWavController.m:325 */
"Removing file failed." = "Konnte Datei nicht lschen.";
/* File: MP3ToWavController.m:323 */
"Removing temporary file %@." = "Lsche temporre Datei %@.";
/* File: MP3ToWavController.m:347 */
"Terminating process." = "Beende Vorgang.";
gnustep-MP3ToWav-0.4.1/MP3ToWavController.h000064400000000000000000000026121227754251000203600ustar00rootroot00000000000000/* vim: set ft=objc ts=4 nowrap: */
/*
* MP3ToWavController.h
*
* Copyright (c) 2005
*
* Author: Andreas Heppel <aheppel@web.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#ifndef MP3TOWAVCONTROLLER_H_INC
#define MP3TOWAVCONTROLLER_H_INC

#include <mad.h>

#include <Foundation/Foundation.h>

#include "ExternalTools.h"
#include "PlayBuffer.h"

#define Output @"Output"

typedef struct {
ProcessStatus processStatus;
NSString *trackName;
double trackProgress;
double entireProgress;
} SConvertStatus;

@interface MP3ToWavController : NSObject <BurnTool, AudioConverter>
{
SConvertStatus convStatus;
NSLock *statusLock;

NSArray *allTracks;
int currentTrack;
unsigned long trackSize;

PlayBuffer *playBuffer;
}

@end

#endif
gnustep-MP3ToWav-0.4.1/MP3ToWavController.m000064400000000000000000000142711227754251000203710ustar00rootroot00000000000000/* vim: set ft=objc ts=4 et sw=4 nowrap: */
/*
* MP3ToWavController.m
*
* Copyright (c) 2005
*
* Author: Andreas Heppel <aheppel@web.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <sys/types.h>
#include <sys/wait.h>
#include <ao/ao.h>

#include "MP3ToWavController.h"
#include "MadFunctions.h"

#include "Constants.h"
#include "Functions.h"
#include "Track.h"

#ifdef _
#undef _
#endif

#define _(X) \
[[NSBundle bundleForClass: [self class]] localizedStringForKey:(X) value:@"" table:nil]



static MP3ToWavController *singleInstance = nil;

@interface MP3ToWavController (Private)
- (void) sendOutputString: (NSString *) outString;
- (void) setStatus: (ProcessStatus) status;
- (NSString *) makeOutfileNameForTrack: (NSString *)trackName
tempDir: (NSString *)tempDir;
@end

//
// private interface
//

@implementation MP3ToWavController (Private)

- (NSString *) makeOutfileNameForTrack: (NSString *)trackName
tempDir: (NSString *)tempDir
{
NSString *outName;
NSString *baseName = [[trackName lastPathComponent] stringByDeletingPathExtension];

outName = [tempDir stringByAppendingPathComponent:
[NSString stringWithFormat: @"%@.wav", baseName]];

return outName;
}

- (void) sendOutputString: (NSString *) outString
{
NSString *outLine;

outLine = [NSString stringWithFormat: @"%@", outString];

[[NSDistributedNotificationCenter defaultCenter]
postNotificationName: ExternalToolOutput
object: nil
userInfo: [NSDictionary dictionaryWithObject: outLine forKey: Output]];
}

- (void) setStatus: (ProcessStatus) status
{
[statusLock lock];
convStatus.processStatus = status;
[statusLock unlock];
}

@end

//
// public interface
//

@implementation MP3ToWavController

- (id) init
{
self = [super init];

if (self) {
statusLock = [NSLock new];
playBuffer = nil;
}

return self;
}


- (void) dealloc
{
singleInstance = nil;
RELEASE(statusLock);

[super dealloc];
}

//
// BurnTool methods
//

- (NSString *) name
{
return @"mp3towav";
}

- (id<PreferencesModule>) preferences;
{
return nil;
}

- (id<PreferencesModule>) parameters;
{
return nil;
}

- (void) cleanUp
{
/*
* No need to clean anything, as we forget about what
* we ripped.
*/
}


//
// class methods
//
+ (id) singleInstance
{
if (! singleInstance) {
singleInstance = [[MP3ToWavController alloc] init];
}

return singleInstance;
}


//
// AudioConverter methods
//
- (NSString *) fileType
{
return @"mp3";
}

/**
* <p>We create a temporary file buffer and make it calculate its
* size. This size is of type @c mad_timer_t which must be converted
* to audio CD frames using the function @c mad_timer_count.</p>
*/
- (long) duration: (NSString *)fileName
{
long duration;
PlayBuffer *pb = [PlayBuffer new];
[pb calcLength: fileName];
duration = mad_timer_count([pb duration], MAD_UNITS_75_FPS);
DESTROY(pb);
return duration;
}

/*
* <p>Calculate the size in bytes by converting the number of
* frames into audio CD size.</p>
*/
- (unsigned) size: (NSString *)fileName
{
long duration = [self duration: fileName];
unsigned size = framesToAudioSize(duration);
return size;
}


- (SConvertStatus) getStatus
{
SConvertStatus status;
Track *track = [allTracks objectAtIndex: currentTrack];
int count = [allTracks count];

[statusLock lock];
convStatus.trackName = [track description];
if (track != nil)
convStatus.trackProgress = [playBuffer percentDone];
else {
convStatus.trackProgress = 0;
}
if (count == 0) {
convStatus.entireProgress = 0;
} else {
convStatus.entireProgress = currentTrack * 100 / count;
convStatus.entireProgress += convStatus.trackProgress / count;
}

status = convStatus;
[statusLock unlock];

return status;
}

- (BOOL) convertTracks: (NSArray *)tracks
withParameters: (NSDictionary *) parameters
{
BOOL ret = YES;
NSString *fileName;
Track *track;
NSDictionary *sesDefaults = [parameters objectForKey: @"SessionParameters"];

struct mad_decoder decoder;

allTracks = tracks;

convStatus.entireProgress = 0;
convStatus.trackProgress = 0;

/*
* Initialize the audio output library.
*/
ao_initialize();

[self setStatus: isConverting];

for (currentTrack = 0; (currentTrack < [allTracks count]) && (ret != NO); currentTrack++) {
/*
* Did the user click abort?
*/
if (convStatus.processStatus == isCancelled) {
break;
}

track = [allTracks objectAtIndex: currentTrack];

fileName = [self makeOutfileNameForTrack: [track source]
tempDir: [sesDefaults objectForKey: @"TempDirectory"]];

[track setStorage: fileName];

playBuffer = [PlayBuffer new];
[playBuffer setInFile: [track source] outFile: fileName];

mad_decoder_init(&decoder, playBuffer, read_from_mmap, read_header, /*filter*/0,
output, /*error*/0, /* message */ 0);

mad_decoder_run(&decoder, MAD_DECODER_MODE_SYNC);

mad_decoder_finish(&decoder);
DESTROY(playBuffer);
}

ao_shutdown();

if (convStatus.processStatus == isConverting) {
[self setStatus: isStopped];
}

allTracks = nil;
return ret;
}

- (BOOL) stop: (BOOL)immediately
{
if (convStatus.processStatus == isConverting) {
[self sendOutputString: _(@"Terminating process.")];
[self setStatus: isCancelled];
[playBuffer stop];
}
return YES;
}

@end
gnustep-MP3ToWav-0.4.1/MadFunctions.h000064400000000000000000000005431227754251000173270ustar00rootroot00000000000000#ifndef MADFUNCTIONS_H_INC
#define MADFUNCTIONS_H_INC

#include <mad.h>

enum mad_flow read_from_mmap(void *data, struct mad_stream *stream);

enum mad_flow read_header(void *data, struct mad_header const * header);

enum mad_flow output(void *data,
struct mad_header const *header,
struct mad_pcm *pcm);

#endif
gnustep-MP3ToWav-0.4.1/MadFunctions.m000064400000000000000000000035061227754251000173360ustar00rootroot00000000000000#include <unistd.h>
#include <sys/mman.h>
#include <stdio.h>
#include <limits.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

#include "PlayBuffer.h"

unsigned long current_frame=0;

enum mad_flow read_from_mmap(void *data, struct mad_stream *stream)
{
PlayBuffer *playbuf = (PlayBuffer *)data;
return [playbuf readFromMmap: stream];
}

char * layerstring(enum mad_layer layer)
{
switch(layer)
{
case MAD_LAYER_I:
return "I";
case MAD_LAYER_II:
return "II";
case MAD_LAYER_III:
return "III";
default:
return "?";
}
}

char * modestring(enum mad_mode mode)
{
switch(mode)
{
case MAD_MODE_SINGLE_CHANNEL:
return "mono";
case MAD_MODE_DUAL_CHANNEL:
return "dual-channel";
case MAD_MODE_JOINT_STEREO:
return "joint-stereo";
case MAD_MODE_STEREO:
return "stereo";
default:
return "?";
}
}

char * modestringucase(enum mad_mode mode)
{
switch(mode)
{
case MAD_MODE_SINGLE_CHANNEL:
return "Single-Channel";
case MAD_MODE_DUAL_CHANNEL:
return "Dual-Channel";
case MAD_MODE_JOINT_STEREO:
return "Joint-Stereo";
case MAD_MODE_STEREO:
return "Stereo";
default:
return "?";
}
}

enum mad_flow read_header(void *data, struct mad_header const * header)
{
PlayBuffer *playbuf = (PlayBuffer *)data;
return [playbuf readHeader: header];
}


enum mad_flow output(void *data,
struct mad_header const *header,
struct mad_pcm *pcm)
{
PlayBuffer *playbuf = (PlayBuffer *)data;
return [playbuf writeOutput: header pcmData: pcm];
}
gnustep-MP3ToWav-0.4.1/PlayBuffer.h000064400000000000000000000040001227754251000167640ustar00rootroot00000000000000/* vim: set ft=objc ts=4 et sw=4 nowrap: */
/*
* PlayBuffer.m
*
* Copyright (c) 2005
*
* Author: Andreas Schik <aheppel@web.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#ifndef PLAYBUFFER_H_INC
#define PLAYBUFFER_H_INC

#include <sys/types.h>
#include <ao/ao.h>
#include <mad.h>

#include <Foundation/Foundation.h>

@interface PlayBuffer : NSObject
{
int fd;

/* The buffer of raw mpeg data for libmad to decode */
void * buf;

/* length of the current stream, corrected for id3 tags */
ssize_t length;

/* have we finished fetching this file? (only in non-mmap()'ed case */
int done;

/* total number of frames */
unsigned long totalFrames;

/* total duration of the file */
mad_timer_t duration;

unsigned long currentFrame;

/*
* Output related ivars.
*/
NSString *outputFile;
ao_device *playDevice;

BOOL stopPlaying;
}

- (id) init;

- (void) stop;

/*
* Access methods
*/
- (mad_timer_t) duration;

- (BOOL) calcLength: (NSString *)file;
- (NSString *) setInFile: (NSString *)inFile outFile: (NSString *)outFile;
- (double) percentDone;

- (enum mad_flow) readFromMmap: (struct mad_stream *)stream;
- (enum mad_flow) readHeader: (struct mad_header const *) header;
- (enum mad_flow) writeOutput: (struct mad_header const *) header pcmData: (struct mad_pcm *)pcm;

@end

#endif
gnustep-MP3ToWav-0.4.1/PlayBuffer.m000064400000000000000000000314001227754251000167750ustar00rootroot00000000000000/* vim: set ft=objc ts=4 et sw=4 nowrap: */
/*
* PlayBuffer.m
*
* Copyright (c) 2005
*
* Author: Andreas Schik <aheppel@web.de>
*
* This file contains code from mpg321 by Joe Drew.
* Copyright (C) 2001 Joe Drew
*
* mpg321 is originally based heavily upon:
* plaympeg - Sample MPEG player using the SMPEG library
* Copyright (C) 1999 Loki Entertainment Software
*
* Also uses some code from
* mad - MPEG audio decoder
* Copyright (C) 2000-2001 Robert Leslie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <mad.h>

#include "PlayBuffer.h"


/* XING parsing is from the MAD winamp input plugin */
struct xing {
int flags;
unsigned long frames;
unsigned long bytes;
unsigned char toc[100];
long scale;
};

enum {
XING_FRAMES = 0x0001,
XING_BYTES = 0x0002,
XING_TOC = 0x0004,
XING_SCALE = 0x0008
};

# define XING_MAGIC (('X' << 24) | ('i' << 16) | ('n' << 8) | 'g')


/* The following two routines and data structure are from the ever-brilliant
Rob Leslie.
*/

struct audio_dither {
mad_fixed_t error[3];
mad_fixed_t random;
};

/*
* NAME: prng()
* DESCRIPTION: 32-bit pseudo-random number generator
*/
static inline
unsigned long prng(unsigned long state)
{
return (state * 0x0019660dL + 0x3c6ef35fL) & 0xffffffffL;
}

/*
* NAME: audio_linear_dither()
* DESCRIPTION: generic linear sample quantize and dither routine
*/
inline
signed long audio_linear_dither(unsigned int bits, mad_fixed_t sample,
struct audio_dither *dither)
{
unsigned int scalebits;
mad_fixed_t output, mask, random;

enum {
MIN = -MAD_F_ONE,
MAX = MAD_F_ONE - 1
};

/* noise shape */
sample += dither->error[0] - dither->error[1] + dither->error[2];

dither->error[2] = dither->error[1];
dither->error[1] = dither->error[0] / 2;

/* bias */
output = sample + (1L << (MAD_F_FRACBITS + 1 - bits - 1));

scalebits = MAD_F_FRACBITS + 1 - bits;
mask = (1L << scalebits) - 1;

/* dither */
random = prng(dither->random);
output += (random & mask) - (dither->random & mask);

dither->random = random;

/* clip */
if (output > MAX) {
output = MAX;

if (sample > MAX)
sample = MAX;
}
else if (output < MIN) {
output = MIN;

if (sample < MIN)
sample = MIN;
}

/* quantize */
output &= ~mask;

/* error feedback */
dither->error[0] = sample - output;

/* scale */
return output >> scalebits;
}


@interface PlayBuffer (Private)
- (void) openPlayDevice: (struct mad_header const *)header;
- (void) scanFile: (void *) ptr length: (ssize_t) len;
- (int) parseXing: (struct xing *)xing bits: (struct mad_bitptr) ptr bitlen: (unsigned int) bitlen;
@end

@implementation PlayBuffer (Private)

- (void) openPlayDevice: (struct mad_header const *)header
{
ao_sample_format format;

format.bits = 16;
format.rate = header->samplerate;
format.channels = 2;

/* mad gives us little-endian data; we swap it on big-endian targets, to
big-endian format, because that's what most drivers expect. */
format.byte_format = AO_FMT_NATIVE;

int driver_id = ao_driver_id("wav");
ao_option *ao_options = NULL;

/*
* Open theoutput file for overwriting.
*/
if((playDevice = ao_open_file(driver_id, [outputFile cString], 1, &format, ao_options))==NULL) {
playDevice = NULL;
}
}

- (void) scanFile: (void *) ptr length: (ssize_t) len;
{
struct mad_stream stream;
struct mad_header header;
struct xing xing;

unsigned long bitrate = 0;
int has_xing = 0;
int is_vbr = 0;

mad_stream_init(&stream);
mad_header_init(&header);

mad_stream_buffer(&stream, ptr, len);

totalFrames = 0;

/* There are three ways of calculating the length of an mp3:
1) Constant bitrate: One frame can provide the information
needed: # of frames and duration. Just see how long it
is and do the division.
2) Variable bitrate: Xing tag. It provides the number of
frames. Each frame has the same number of samples, so
just use that.
3) All: Count up the frames and duration of each frames
by decoding each one. We do this if we've no other
choice, i.e. if it's a VBR file with no Xing tag.
*/

while (1) {
if (mad_header_decode(&header, &stream) == -1) {
if (MAD_RECOVERABLE(stream.error))
continue;
else
break;
}

/* Limit xing testing to the first frame header */
if (!totalFrames++) {
if([self parseXing: &xing bits: stream.anc_ptr bitlen: stream.anc_bitlen]) {
is_vbr = 1;

if (xing.flags & XING_FRAMES) {
/* We use the Xing tag only for frames. If it doesn't have that
information, it's useless to us and we have to treat it as a
normal VBR file */
has_xing = 1;
totalFrames = xing.frames;
break;
}
}
}

/* Test the first n frames to see if this is a VBR file */
if (!is_vbr && !(totalFrames > 20)) {
if (bitrate && header.bitrate != bitrate) {
is_vbr = 1;
} else {
bitrate = header.bitrate;
}
} else if (!is_vbr) {
/* We have to assume it's not a VBR file if it hasn't already been
marked as one and we've checked n frames for different bitrates */
break;
}

mad_timer_add(&duration, header.duration);
}

if (!is_vbr) {
double time = (len * 8.0) / (header.bitrate); /* time in seconds */
double timefrac = (double)time - ((long)(time));
long nsamples = 32 * MAD_NSBSAMPLES(&header); /* samples per frame */

/* samplerate is a constant */
totalFrames = (long) (time * header.samplerate / nsamples);

mad_timer_set(&duration, (long)time, (long)(timefrac*100), 100);
} else if (has_xing) {
/* modify header.duration since we don't need it anymore */
mad_timer_multiply(&header.duration, totalFrames);
duration = header.duration;
} else {
/* the durations have been added up, and the number of frames
counted. We do nothing here. */
}

mad_header_finish(&header);
mad_stream_finish(&stream);
}

- (int) parseXing: (struct xing *)xing bits: (struct mad_bitptr) ptr bitlen: (unsigned int) bitlen
{
if (bitlen < 64 || mad_bit_read(&ptr, 32) != XING_MAGIC)
goto fail;

xing->flags = mad_bit_read(&ptr, 32);
bitlen -= 64;

if (xing->flags & XING_FRAMES) {
if (bitlen < 32)
goto fail;

xing->frames = mad_bit_read(&ptr, 32);
bitlen -= 32;
}

if (xing->flags & XING_BYTES) {
if (bitlen < 32)
goto fail;

xing->bytes = mad_bit_read(&ptr, 32);
bitlen -= 32;
}

if (xing->flags & XING_TOC) {
int i;

if (bitlen < 800)
goto fail;

for (i = 0; i < 100; ++i)
xing->toc[i] = mad_bit_read(&ptr, 8);

bitlen -= 800;
}

if (xing->flags & XING_SCALE) {
if (bitlen < 32)
goto fail;

xing->scale = mad_bit_read(&ptr, 32);
bitlen -= 32;
}

return 1;

fail:
xing->flags = 0;
return 0;
}

@end


@implementation PlayBuffer

- (id) init
{
self = [super init];
if (self != nil) {
fd = -1;
buf = NULL;
length = 0;
done = 0;
totalFrames = 0;
stopPlaying = NO;
currentFrame = 0;
outputFile = nil;
mad_timer_reset(&duration);
}
return self;
}

- (void) dealloc
{
munmap(buf, length);

if (fd >= 0)
close (fd);

RELEASE(outputFile);
[super dealloc];
}

- (void) stop
{
stopPlaying = YES;
}


/*
* Access methods
*/
- (mad_timer_t) duration
{
return duration;
}


/* The following two functions are adapted from mad_timer, from the
libmad distribution */
- (BOOL) calcLength: (NSString *)file
{
int f;
struct stat filestat;
void *fdm;
char buffer[3];

f = open([file cString], O_RDONLY);

if (f < 0) {
return NO;
}

if (fstat(f, &filestat) < 0) {
close(f);
return NO;
}

if (!S_ISREG(filestat.st_mode)) {
close(f);
return NO;
}

/* TAG checking is adapted from XMMS */
length = filestat.st_size;

if (lseek(f, -128, SEEK_END) < 0) {
/* File must be very short or empty. Forget it. */
close(f);
return NO;
}

if (read(f, buffer, 3) != 3) {
close(f);
return NO;
}

if (!strncmp(buffer, "TAG", 3)) {
length -= 128; /* Correct for id3 tags */
}

fdm = mmap(0, length, PROT_READ, MAP_SHARED, f, 0);
if (fdm == MAP_FAILED) {
close(f);
return NO;
}

/* Scan the file for a XING header, or calculate the length,
or just scan the whole file and add everything up. */
[self scanFile: fdm length: length];

if (munmap(fdm, length) == -1) {
close(f);
return NO;
}

if (close(f) < 0) {
return NO;
}

return YES;
}


- (NSString *) setInFile: (NSString *)inFile outFile: (NSString *)outFile
{
struct stat stat;

if((fd = open([inFile cString], O_RDONLY)) == -1) {
return [NSString stringWithFormat: @"%@: %s\n", inFile, strerror(errno)];
}

if(fstat(fd, &stat) == -1) {
return [NSString stringWithFormat: @"%@: %s\n", inFile, strerror(errno)];
}

if (!S_ISREG(stat.st_mode)) {
return [NSString stringWithFormat: @"%@: %s\n", inFile, strerror(errno)];
}

[self calcLength: inFile];

if((buf = mmap(0, length, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) {
return [NSString stringWithFormat: @"%@: %s\n", inFile, strerror(errno)];
}


outputFile = [outFile copy];
return nil;
}

- (double) percentDone
{
double ret = 0.;
if (totalFrames != 0)
ret = ((double)currentFrame * 100.) / (double)totalFrames;
return ret;
}

- (enum mad_flow) readFromMmap: (struct mad_stream *)stream;
{
void *mpegdata = NULL;

/* libmad asks us for more data when it runs out. We don't have any more,
so we want to quit here. */
if (done) {
return MAD_FLOW_STOP;
}

mpegdata = buf;

done = 1;

mad_stream_buffer(stream, mpegdata, length - (mpegdata - buf));

return MAD_FLOW_CONTINUE;
}

- (enum mad_flow) readHeader: (struct mad_header const *) header
{
if (stopPlaying) {
return MAD_FLOW_STOP;
}

currentFrame++;

return MAD_FLOW_CONTINUE;
}

- (enum mad_flow) writeOutput: (struct mad_header const *) header pcmData: (struct mad_pcm *)pcm
{
register int nsamples = pcm->length;
mad_fixed_t const *left_ch = pcm->samples[0], *right_ch = pcm->samples[1];

static unsigned char stream[1152*4]; /* 1152 because that's what mad has as a max; *4 because
there are 4 distinct bytes per sample (in 2 channel case) */
static unsigned int rate = 0;
static int channels = 0;
static struct audio_dither dither;

register char * ptr = stream;
register signed int sample;
register mad_fixed_t tempsample;

/* We need to know information about the file before we can open the playdevice
in some cases. So, we do it here. */
if (!playDevice) {
channels = MAD_NCHANNELS(header);
rate = header->samplerate;
[self openPlayDevice: header];
}
if (!playDevice)
return MAD_FLOW_STOP;

if (pcm->channels == 2) {
while (nsamples--) {
tempsample = (mad_fixed_t)(*left_ch++);
sample = (signed int) audio_linear_dither(16, tempsample, &dither);

#ifndef WORDS_BIGENDIAN
*ptr++ = (unsigned char) (sample >> 0);
*ptr++ = (unsigned char) (sample >> 8);
#else
*ptr++ = (unsigned char) (sample >> 8);
*ptr++ = (unsigned char) (sample >> 0);
#endif

tempsample = (mad_fixed_t)(*right_ch++);
sample = (signed int) audio_linear_dither(16, tempsample, &dither);
#ifndef WORDS_BIGENDIAN
*ptr++ = (unsigned char) (sample >> 0);
*ptr++ = (unsigned char) (sample >> 8);
#else
*ptr++ = (unsigned char) (sample >> 8);
*ptr++ = (unsigned char) (sample >> 0);
#endif
}

ao_play(playDevice, stream, pcm->length * 4);
} else {
while (nsamples--) {
tempsample = (mad_fixed_t)(*left_ch++);
sample = (signed int) audio_linear_dither(16, tempsample, &dither);

/* Just duplicate the sample across both channels. */
#ifndef WORDS_BIGENDIAN
*ptr++ = (unsigned char) (sample >> 0);
*ptr++ = (unsigned char) (sample >> 8);
*ptr++ = (unsigned char) (sample >> 0);
*ptr++ = (unsigned char) (sample >> 8);
#else
*ptr++ = (unsigned char) (sample >> 8);
*ptr++ = (unsigned char) (sample >> 0);
*ptr++ = (unsigned char) (sample >> 8);
*ptr++ = (unsigned char) (sample >> 0);
#endif
}

ao_play(playDevice, stream, pcm->length * 4);
}

return MAD_FLOW_CONTINUE;
}

@end
gnustep-MP3ToWav-0.4.1/README000064400000000000000000000013371227754251000154460ustar00rootroot00000000000000MP3ToWav.bundle
===============
MP3ToWav.bundle is a supportig bundle for Burn.app. It implements
API for Burn.app's the audio file conversion bundles. MP3ToWav.bundle
converts, as its name implies, mp3 audio files into wav audio files
which can be burned onto a CD playable in your home stereo.


Requirements
============

Burn.app
--------
As MP3ToWav.bundle is a suporting bundle for Burn.app you will of
course need the application. Otherwise thebundle is of no use
for you.
Download the latest version from here:
http://gsburn.sourceforge.net


Installation
============

In the bundle's source code directory type:

> make
> make install

This will install the bundle in a place where it can be automatically
found by Burn.app.
gnustep-MP3ToWav-0.4.1/iconMP3ToWav.tiff000064400000000000000000000106321227754251000176670ustar00rootroot00000000000000II*HxY TTW}FAGb8EAhB(HC% (68$ب T@ !N88QvsH]^zosϰE߭nJ :>o\KЗMN!!-A0P[[ҟeb[3>G _)|5ign
Z߶oq!EiV[;$ZVYG~RsQ^_}<4djF~Exa=+B{/ARuJ'EEQP֭y8\)ٳ()ق9a<cڏ  "J꣪*dV{
^G$*׮bTT ?Ə':W/Bޙ>:CŤ{缎N9ɛ=_5J &&cQZ-|>oh8&l`5/obl̈́ׯDf_}U:D[NFp"wfCg̟kR݂5:{C[Om6 |
@1G ߳}SCbǸs^%⿘޽TJ@xMR/5^&ǀ}?:b(Œk7GAMMܬ=zBKNCh{"L *)Ay{j߃𮽽֏nEt" }!l3~Tիe8uj7VVV8~G-hm%l<YCIQ_uOWrם]/|߿e!OOBJ 1bD_PmDHڹyWdW.g.WWW:>+WPWWC=×`@FYo:#S\Ye;v#2Lɓ)ry;A&6MWMMgwe"o>/w4^2ڸ;'l"9_>+={JN7l]]a♣F#++ɋgɓ'55w+*ݼw#@kSC>H%tɒ"Ǩ<QA1OofSw4H[BӓA7`ժU5Q#SxV=77vƌ #G

#Zd6ɓ2 Oѣwpˍ0#)4schW.rB&03s|pg pa?Hl5}#Dq270`LzC%)XKꤖ>}P飌(ꡣG!9韢ְii-kiySDĊ^TV3fmXpxue;< ##A^ҿs@3Bw^JK>}u|*+D<~K.vڇS??y,'_ˋ6 =TXQ_زwRSzDX*)xI~d9ܹ 89n;Yj+AAb1C{{̙49s=|sѓڴ,Fؾ#as=}u]\\&N~㕟WTwEZe1HJzO~!G2Ӳo

YsСXDψ#8̤?*縮sALdY؝'le~alז U}9aݞ"cvH^)|SQR2Je#?0zuW~ɬ7Y;ldU_C?}s%wfϱƱ>g/'Ϧ-ݣ'$!p/("(Q-G%Bv<om\ֶw+k煤A42l
3sq֟ܫx/D;SŸ),XOOO ,,L`pww3BBBh"x#pMU2u
Snj6"Kr=!\9o{= yXb6_>_#/7QQQxbrW#GpaR91#gJ q.qMsOex6E|ܸg88x\g΋^[Xa>d=oJ5a--C:51{lL>o&aeM(ɌGTn8bMLrk4};omlp<+tiaPGgb? yflي1ضm␲+ i4wŚZ׮0aƌ{+'/oy` 70!A_N?\\-w7m4W#c)\oǼM>#Cu7v""%5jo"$ƞ,|[\h<-Q䄱pR55FDz0| 7wS,-S OS UMqrk{G?KiqcA:b?8_ 7E۸v*ͤ(//ǴiӠ7m"F@Jb4j/Ed^8<Iv*ODI]O,}:tDo.ԔG3f`P.ʇlwC8t[>s5U+j.V`Y9r5k`$7`d>IX|ƺXiܓJ&MyEne)5+ϕho9S[/^<NCFZ:*Nw Fӌ`lc0;9DN_8cs{$ˑ7\Ї?yd3w;Sa_nq_fC=u1<tn,

pu|
jox)`Jw9uI]i5j{ E?(FWCii >gX}Az.\_D5kB?T2336܀%&cBc.}K?~p\ӹn ]ں\@ũLl3{FShM]47CDD8 Qseq׃>b[' 89Za(gvtWB0jbb|P]SEsC%jfmH?Yu.3vxu9,΁lܹ~wU Ts},r\sQQ>wvqm bϛgb8$$~N&1|@?e\ڞ<!y)nTE''''?h,,X1y9!sm(I)/oOZb)ſ%EWEbm/@:$,,,`mcW\;mmm KsF LCbԝHKO%Kr/աQ :VCC.ަu1/hxyy m-=s^?>-[Fa:|daKqI>;$jR]];?kk+ILt7ꉦy(m)1Gs/\PaLWdd|8u8.]ŭ[h$=s~a2 ?ucȑс!.CP iƟ-!!֭ !0ȟfȪz
4"u4-g1k,
Ǝ¬aogEw&A<s>O^^"##VQ5v.Bss2d cgɒ%?%̳xמ3g0)) 111x===\"H[lA\\8=O>`]sM3&,Шdxy|^ʟq}~}{s9x"/%3|>aML JQ^󽧿)!=k\GI[^&UKYc$QOGR3뭗:M+W/Î?׿L00&E.t@@(R/home/aheppel/Projekte/GSburn/Bundles/CDparanoia/iconCDparanoia.tiffCreated with The GIMPHH
 
: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
: Michael Shigorin