Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 03.08.2009, 19:48   #1
SkAndrew
Форумчанин
 
Регистрация: 05.04.2008
Сообщений: 244
По умолчанию Прошу помощи в конвертации на Делфи кода от С++.

Добрый день!

Прошу помощи в конвертации на Делфи следующего кода:

Код:
typedef struct {
      float speed;
      int buflen;
      short *buf;
      float readpos;
      int flags,freq;
      HSTREAM str,rstr;
} RESAMPSTUFF;

/* resample the buffer - far from optimal but gets the job done */
DWORD resamp(short *buffer, DWORD length, RESAMPSTUFF *r)
{
      DWORD p,l;
      double i;
      float f,bufsamp;
      if (r->flags&BASS_SAMPLE_MONO) { /* mono */
            bufsamp=(r->buflen/2)-1;
            for (l=0;l<length && r->readpos<bufsamp;l+=2) {
                  f=(float)modf(r->readpos,&i);
                  p=(int)i;
                  *buffer++=(short)((1.0-f)*r->buf[p]+f*r->buf[p+1]);
                  r->readpos+=r->speed;
            }
            p=(int)r->readpos;
            r->readpos=(float)modf(r->readpos,&i);
            r->buflen-=2*p;
            if (r->buflen<0) {
                  r->readpos+=-r->buflen/2;
                  r->buflen=0;
            } else
                  memmove(r->buf,r->buf+p,r->buflen);
      } else { /* stereo */
            bufsamp=(r->buflen/4)-1;
            for (l=0;l<length && r->readpos<bufsamp;l+=4) {
                  f=(float)modf(r->readpos,&i);
                  p=2*(int)i;
                  *buffer++=(short)((1.0-f)*r->buf[p]+f*r->buf[p+2]);
                  *buffer++=(short)((1.0-f)*r->buf[p+1]+f*r->buf[p+3]);
                  r->readpos+=r->speed;
            }
            p=2*(int)r->readpos;
            r->readpos=(float)modf(r->readpos,&i);
            r->buflen-=2*p;
            if (r->buflen<0) {
                  r->readpos+=-r->buflen/4;
                  r->buflen=0;
            } else
                  memmove(r->buf,r->buf+p,r->buflen);
      }
      return l;
}
ниже моя интерпретация, но код не работает, ошибки. подскажите как их исправить:

Код:
  RESAMPSTUFF = record
    speed : Double;
    buflen : Integer;
    buf : array[0..50000] of SmallInt;
    readpos : Double;
    flags, freq : Integer;
    str, rstr : HSTREAM;
  end;

// resample the buffer - far from optimal but gets the job done
function resamp(buffer : PSmallInt; length : DWORD; r : RESAMPSTUFF) : DWORD;
     var p, l : DWORD;
         i : Double;
         f, bufsamp : Double;
begin
  if (r.flags = BASS_SAMPLE_MONO) then  // mono
  begin
    bufsamp :=(r.buflen/2)-1;
    l := 0;
    repeat
       f := fmod(r.readpos, i);
       p := Trunc(i);
       buffer^ := Round((1.0-f)*r.buf[p]+f*r.buf[p+1]);
       r.readpos := r.readpos+r.speed;
       l :=l+2;
       Inc(buffer);
    until (l<length) and (r.readpos<bufsamp);
    p := Trunc(r.readpos);
    r.readpos := fmod(r.readpos, i);
    r.buflen :=r.buflen-2*Integer(p);
    if (r.buflen<0) then
    begin
      r.readpos := r.readpos+(-r.buflen/2);
      r.buflen := 0;
    end
    else
      move(r.buf, r.buf+p, r.buflen);
  end
  else
  begin // stereo
    bufsamp :=(r.buflen/4)-1;
    l := 0;
    repeat
       f := fmod(r.readpos, i);
       p := 2*Trunc(i);
       buffer^ := Round((1.0-f)*r.buf[p]+f*r.buf[p+2]);
       buffer^ := Round((1.0-f)*r.buf[p+1]+f*r.buf[p+3]);
       r.readpos := r.readpos+r.speed;
       l :=l+4;
       Inc(buffer);
    until (l<length) and (r.readpos<bufsamp);
    p := 2*Trunc(r.readpos);
    r.readpos := fmod(r.readpos, i);
    r.buflen :=r.buflen-2*Integer(p);
    if (r.buflen<0) then
    begin
      r.readpos := r.readpos+(-r.buflen/4);
      r.buflen := 0;
    end
    else
      move(r.buf,r.buf+p,r.buflen);
  end;
  Result := l;
end;
спасибо!

Последний раз редактировалось SkAndrew; 03.08.2009 в 20:43.
SkAndrew вне форума Ответить с цитированием
Старый 04.08.2009, 00:20   #2
Somebody
Участник клуба
 
Регистрация: 08.10.2007
Сообщений: 1,185
По умолчанию

float -> Single
short *buf; -> PSmallInt
RESAMPSTUFF *r -> r: PRESAMPSTUFF (надо определить тогда тип - указатель на эту структуру)
if (r->flags&BASS_SAMPLE_MONO) -> if r.flags and BASS_SAMPLE_MONO <> 0
for -> while, а не repeat, если repeat всё же уместен по контексту, то условие обратное: (l>=length) or (r.readpos>=bufsamp);
p=(int)r->readpos; -> Round
memmove(dst, src, count) -> move(dst, src, count)
p=2*(int)i; -> Round
*buffer++= ... -> после = ещё перемещение на следующий элемент

Может, даже наверное, что-то ещё. Но это "дословно", с указателем на массив любого размера в структуре и параметрах функции проблемы. Или надо динамический массив, или если надо чтобы прямо как на C++, то создай тип - массив [0..0], указатель на него и отключи проверку диапазона: {$R-}.
Somebody вне форума Ответить с цитированием
Старый 04.08.2009, 00:41   #3
SkAndrew
Форумчанин
 
Регистрация: 05.04.2008
Сообщений: 244
По умолчанию

Спасибо за подсказки, а Вам сложно исправить мой дельфийский перевод и как в этом случае должна на паскале выглядеть строка :

Код:
memmove(r->buf,r->buf+p,r->buflen);
Спасибо!
SkAndrew вне форума Ответить с цитированием
Старый 04.08.2009, 12:40   #4
Somebody
Участник клуба
 
Регистрация: 08.10.2007
Сообщений: 1,185
По умолчанию

Если исправлять перевод, то надо исправлять с указателями/массивами. Например, тут непонятно, что за modf, если он свой, на Delphi, можно всё переделать на динамические массивы, а если на C/C++, то уже надо делать чтобы было так же, как на C.
В memmove и move порядок параметров разный:
Код:
memmove(r->buf, r->buf+p, r->buflen);
move(r.buf+p, r.buf, r.buflen);
Somebody вне форума Ответить с цитированием
Старый 04.08.2009, 16:04   #5
SkAndrew
Форумчанин
 
Регистрация: 05.04.2008
Сообщений: 244
По умолчанию

Спасибо за помощь, но на этих строчках

Код:
move(r.buf+p, r.buf, r.buflen);
компилятор выдает ошибку на

Код:
r.buf+p
Где проблема и как ее устранить?
Спасибо

Последний раз редактировалось SkAndrew; 04.08.2009 в 16:22.
SkAndrew вне форума Ответить с цитированием
Старый 04.08.2009, 16:28   #6
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Правильно так нельзя.Mоve это не проглотит. Что ты хочешь сделать действием r.buf+p?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 04.08.2009, 22:29   #7
SkAndrew
Форумчанин
 
Регистрация: 05.04.2008
Сообщений: 244
По умолчанию

Исходник выложен в полном виде в первом посте.
В Си это работает, а как записать в паскале?
Спасибо.
SkAndrew вне форума Ответить с цитированием
Старый 05.08.2009, 11:58   #8
Somebody
Участник клуба
 
Регистрация: 08.10.2007
Сообщений: 1,185
По умолчанию

А, ну да. Там параметры-varы
Код:
(r.buf+p)^, (r.buf)^
И прибавлять числа можно только к указателям типа PChar. Если он не PChar, так что в случае с PSmallInt:
Код:
PSmallInt(PChar(r.buf) + p * sizeof(SmallInt))
move((PChar(r.buf) + p * sizeof(SmallInt))^, r.buf^, r.buflen);
Somebody вне форума Ответить с цитированием
Старый 05.08.2009, 20:28   #9
SkAndrew
Форумчанин
 
Регистрация: 05.04.2008
Сообщений: 244
По умолчанию

Спасибо за ответ, только я не понял нужны обе строчки

Код:
PSmallInt(PChar(r.buf) + p * sizeof(SmallInt))
move((PChar(r.buf) + p * sizeof(SmallInt))^, r.buf^, r.buflen);
или только

Код:
move((PChar(r.buf) + p * sizeof(SmallInt))^, r.buf^, r.buflen);
Спасибо
SkAndrew вне форума Ответить с цитированием
Старый 06.08.2009, 12:41   #10
Somebody
Участник клуба
 
Регистрация: 08.10.2007
Сообщений: 1,185
По умолчанию

Вторая, в первой просто прибавление числа к указателю.
Somebody вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Прошу помощи:) valiza Помощь студентам 0 03.07.2009 11:58
Прошу помощи. Brian Lee Jones Свободное общение 0 19.06.2008 00:21
Прошу помощи в делфи sergeyfsd Помощь студентам 5 23.05.2008 20:39
Прошу помощи! Oksana Общие вопросы Delphi 6 11.02.2007 18:36