PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
main.c
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Copyright 2005, James Lee (jbit<at>jbit<dot>net)
7# Licenced under Academic Free License version 2.0
8# Review ps2sdk README & LICENSE files for further details.
9*/
10
11#include <stdio.h>
12#include <fcntl.h>
13#include <errno.h>
14#include <string.h>
15#include <stdlib.h>
16#include <stdint.h>
17#include "adpcm.h"
18
19#define dprintf(format, args...) \
20 fprintf(stderr, "ps2adpcm(%s): " format, __FUNCTION__, ## args)
21
22typedef struct
23{
24 int Position;
25 int Channel;
26 int ChannelCount;
27 short *Sample;
28 int SampleCount;
29} PcmBuffer;
30
31int GetPCM(void *priv, double *out, int len)
32{
33 int i;
34 PcmBuffer *pcm = priv;
35
36 for (i=0;i<len;i++)
37 {
38 if (pcm->Position+i>=pcm->SampleCount)
39 break;
40 out[i] = pcm->Sample[((pcm->Position+i)*pcm->ChannelCount)+pcm->Channel];
41 }
42 pcm->Position += i;
43
44 return(i);
45}
46
47
48int PutADPCM(void *priv, void *data, int len)
49{
50 FILE *f = priv;
51 int r;
52 r = fwrite(data, 1, len, f);
53 if (r<0)
54 {
55 dprintf("write error (%s)\n", strerror(errno));
56 return(-1);
57 }
58
59 return(r);
60}
61
62int main(int argc, char *argv[])
63{
64 char *infile, *outfile;
65 FILE *fi, *fo;
66 int bpc = 1024; /* ADPCM (16byte, 28sample) blocks per chunk */
67 int loopstart = -1;
68 AdpcmSetup *set[2];
69 PcmBuffer pcm;
70
71 pcm.ChannelCount = 1;
72
73 if (argc<3)
74 {
75 dprintf("usage: %s <PCM Input> <ADPCM Output> -s(tereo) -c[chunksize] -l[loopstart]\n", argv[0]);
76 dprintf("example: %s - output.adpcm -s -c1024 -s1000\n", argv[0]);
77
78 return(1);
79 }
80
81 infile = argv[1];
82 outfile = argv[2];
83
84 for (int i=3;i<argc;i++)
85 {
86 long int num;
87 if (argv[i][0] != '-' || argv[i][1] == '\0')
88 {
89 dprintf("%s: invalid option '%s'\n", argv[0], argv[i]);
90 return(1);
91 }
92 num = strtol(&argv[i][2], NULL, 0);
93 switch(argv[i][1])
94 {
95 case 's': pcm.ChannelCount = 2; break;
96 case 'c':
97 if (num<=0 || num >= 65536)
98 {
99 dprintf("%s: invalid block size (%ld, '%s')\n", argv[0], num, &argv[i][2]);
100 return(1);
101 }
102 bpc = num;
103 break;
104 case 'l':
105 if (num<0)
106 {
107 dprintf("%s: invalid loop start address (%ld, '%s')\n", argv[0], num, &argv[i][2]);
108 return(1);
109 }
110 loopstart = num;
111 break;
112 default:
113 dprintf("%s: unkown option '%s'\n", argv[0], argv[i]);
114 return(1);
115 break;
116 }
117 }
118
119
120 if (!strcmp(infile, "-"))
121 fi = stdin;
122 else
123 {
124 fi = fopen(infile, "rb");
125 if (fi==NULL)
126 {
127 dprintf("Failed to open input file '%s' (%s)\n", infile, strerror(errno));
128 return(1);
129 }
130 }
131
132 fo = fopen(outfile, "wb");
133 if (fo==NULL)
134 {
135 dprintf("Failed to open output file '%s' (%s)\n", outfile, strerror(errno));
136 return(1);
137 }
138
139 for (int i=0;i<pcm.ChannelCount;i++)
140 {
141 set[i] = AdpcmCreate(GetPCM, &pcm, PutADPCM, fo, loopstart);
142 if (set[i]==NULL)
143 {
144 dprintf("Failed to create ADPCM setup\n");
145 return(1);
146 }
147 }
148
149 if (pcm.ChannelCount>1)
150 {
151 set[0]->pad = 1;
152 set[1]->pad = 1;
153 }
154
155 pcm.Sample = malloc((bpc*28)*pcm.ChannelCount*2);
156 do
157 {
158 int i, r;
159 r = fread(pcm.Sample, 2*pcm.ChannelCount, (bpc*28), fi);
160 if (r<0)
161 break;
162 pcm.SampleCount = r;
163
164 for (i=0;i<pcm.ChannelCount;i++)
165 {
166 pcm.Position = 0;
167 pcm.Channel = i;
168 if (AdpcmEncode(set[i], bpc)!=bpc)
169 break;
170 }
171 if (i!=pcm.ChannelCount)
172 break;
173 } while(1);
174 free(pcm.Sample);
175
176 return(0);
177}
178
179